I\'m using Beej\'s Guide to Networking and came across an aliasing issue. He proposes a function to return either the IPv4 or IPv6 address of a particular struct:
The issue has nothing to do with the call to the function. Rather, it's with ((struct sockaddr_in*)sa)->sin_addr. The problem is that sa is a pointer of one type, but you're casting it to a pointer of a different type and then dereferencing it. This breaks a rule called "strict aliasing", which says that variables of different types can never alias. In your case, aliasing to a different type is exactly what you want to do.
The simple solution is to turn off this optimization, which allows aliasing in this manner. On GCC, the flag is -fno-strict-aliasing.
The better solution is to use a union, as mentioned by Nikolai.
void *get_in_addr(struct sockaddr *sa)
{
union {
struct sockaddr *sa;
struct sockaddr_in *sa_in;
struct sockaddr_in6 *sa_in6;
} u;
u.sa = sa;
if (sa->sa_family == AF_INET)
return &(u.sa_in->sin_addr);
else
return &(u.sa_in6->sin6_addr);
}
That said, I can't actually get GCC to give me a warning when using your original code, so I'm not sure if this buys you anything.