2

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?

Global Warrior
  • 5,050
  • 9
  • 45
  • 75

4 Answers4

4

You should use struct in_addr, not just in_addr in c code (when casting too).

Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173
3

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:

1.Typedef the struct in its declaration

typedef struct in_addr {
    /* ... */
} in_addr;

2.Use the 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.

sidyll
  • 57,726
  • 14
  • 108
  • 151
  • 1
    In c++ the two different namespaces still exist and are separate. The difference is in lookup, where for each scope the compiler will first check as in C the general identifier space, and if that fails it will also look in the user defined types identifier space. Check for example: [here](http://stackoverflow.com/a/7970257/36565) or [here](http://stackoverflow.com/a/1675446/36565) – David Rodríguez - dribeas Jan 24 '12 at 12:52
  • Thanks for the comment @DavidRodríguez-dribeas I must admit that my C++ knowledge is poor. I edited the answer slightly. Just to confirm: typedef'ed version with the same name for the struct tag and new type is then perfectly valid in C++, right? – sidyll Jan 24 '12 at 15:14
  • I am not sure about what you exactly mean, but this is ok: `typedef struct A {} B; struct B {};` although confusing. In that context `B` refers to the first type and `struct B` to the second. – David Rodríguez - dribeas Jan 25 '12 at 02:12
  • @DavidRodríguez-dribeas I was refering to the "1st alternative" I posted in the answer, more in the lines of `typedef struct A {} A;`. But your comment answered that. Thanks. – sidyll Jan 25 '12 at 11:41
2

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.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
0

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.

John Bode
  • 119,563
  • 19
  • 122
  • 198