sin*_*oth 24 c sockets strict-aliasing pointer-aliasing
我正在使用Beej的网络指南,并遇到了一个别名问题.他提出了一个函数来返回特定结构的IPv4或IPv6地址:
1 void *get_in_addr( struct sockaddr *sa )
2 {
3 if (sa->sa_family == AF_INET)
4 return &(((struct sockaddr_in*)sa)->sin_addr);
5 else
6 return &(((struct sockaddr_in6*)sa)->sin6_addr);
7 }
Run Code Online (Sandbox Code Playgroud)
这会导致GCC 在第3行为sa吐出严格别名错误.据我所知,这是因为我这样调用这个函数:
struct sockaddr_storage their_addr;
...
inet_ntop(their_addr.ss_family,
get_in_addr((struct sockaddr *)&their_addr),
connection_name,
sizeof connection_name);
Run Code Online (Sandbox Code Playgroud)
我猜测别名与their_addr变量是类型的事实有关,sockaddr_storage而另一个不同类型的指针指向同一个内存.
就是要解决这个症结的最佳方式sockaddr_storage,sockaddr_in以及sockaddr_in6组成工会?看起来这应该是网络中的一个很好的领域,我只是找不到任何有最佳实践的好例子.
此外,如果有人能够准确解释别名问题发生的位置,我会非常感激.
Nik*_*sov 21
我倾向于这样做以使GCC使用类型惩罚做正确的事情,这在工会中是明确允许的:
/*! Multi-family socket end-point address. */
typedef union address
{
struct sockaddr sa;
struct sockaddr_in sa_in;
struct sockaddr_in6 sa_in6;
struct sockaddr_storage sa_stor;
}
address_t;
Run Code Online (Sandbox Code Playgroud)