Reputation: 5110
I have a piece of code which looks like
#include <stdio.h>
#include <netdb.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
struct hostent *server;
server = gethostbyname(argv[1]);
struct in_addr * address=(in_addr * )server->h_addr;
fprintf(stderr,"[%d] [%s] server [%s] \n",__LINE__,__func__,inet_ntoa(*address));
}
When i use g++ compiler it gets compiled but the same gives the following error with gcc compiler
myclient.c: In function ‘main’:
myclient.c:10:31: error: ‘in_addr’ undeclared (first use in this function)
myclient.c:10:31: note: each undeclared identifier is reported only once for each function it appears in
myclient.c:10:41: error: expected expression before ‘)’ token
Am I missing something here?
Upvotes: 2
Views: 1430
Reputation: 59277
It's important to note that C has multiple namespaces. The general namespace includes typedefs and other identifiers, but there is a separate namespace for structs, enums, and unions tags; another one for labels, and also each struct has it's own namespace. In code like this:
struct name {
int name;
} name;
name
means 3 completely different things and this is perfectly legal. To
avoid typing the struct
keyword, programmers often typedef a new name for
the struct and its tag:
typedef struct name {
int name;
} my_struct;
my_struct s1; /* easier than: struct name s1 */
my_struct s2;
In this last example name can even be omitted, unless you want to use a pointer to the struct inside itself. This practice was so common that in C++ the compiler considers the tag a defined type for structs. This is perfectly legal in C++:
struct my_struct {
int name;
};
my_struct s1;
my_struct s2;
And indeed is what's happening in your program. You're using the struct tag as a type, but it's only a valid type in C++. You have two alternatives:
typedef struct in_addr {
/* ... */
} in_addr;
struct
keyword to refer to the struct type(struct in_addr *)
The first one is not applicable since you didn't declare the struct. It already comes that way. So I'd stick with the second.
Upvotes: 3
Reputation: 123458
C and C++ have different rules for struct types; in C++, the keyword struct
creates a class type where all members are public
by default. This type name can stand on its own, unlike in C.
C++ is not merely a superset of C, and there's plenty of code that will compile as one but not the other, or will behave differently because of different semantics.
Upvotes: 0
Reputation: 500157
Change:
struct in_addr * address=(in_addr * )server->h_addr;
to:
struct in_addr * address=(struct in_addr * )server->h_addr;
Also, C (before C99) only allows variable declarations at the top of a block, and struct in_addr * address
isn't.
Upvotes: 2
Reputation: 143061
You should use struct in_addr
, not just in_addr
in c
code (when casting too).
Upvotes: 4