Global Warrior
Global Warrior

Reputation: 5110

Compilation difference C and C++

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

Answers (4)

sidyll
sidyll

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:

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.

Upvotes: 3

John Bode
John Bode

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

NPE
NPE

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

Michael Krelin - hacker
Michael Krelin - hacker

Reputation: 143061

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

Upvotes: 4

Related Questions