【问题标题】:Is the type cast from sockaddr_in* to sockaddr* a violation of "strict aliasing rule"?从 sockaddr_in* 到 sockaddr* 的类型转换是否违反了“严格的别名规则”?
【发布时间】:2021-08-19 06:49:35
【问题描述】:

以下类型从 sockaddr_in* 转换为 sockaddr* 是否违反“严格别名规则”?

“Beej 网络编程指南”(版本 2.3.23)中的示例代码 sn-p。类型转换发生在最后一行。

...
#include <arpa/inet.h>
#define MYPORT 3490
main()
{
int sockfd;
struct sockaddr_in my_addr;
sockfd = socket(PF_INET, SOCK_STREAM, 0); 
my_addr.sin_family = AF_INET; 
my_addr.sin_port = htons(MYPORT); 
my_addr.sin_addr.s_addr = inet_addr("10.12.110.57");
memset(&(my_addr.sin_zero), ’\0’, 8); 
bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));

为方便起见,我将这些结构定义包括在内:

struct sockaddr {
    unsigned short    sa_family;    // address family, AF_xxx
    char              sa_data[14];  // 14 bytes of protocol address
};


// IPv4 AF_INET sockets:

struct sockaddr_in {
    short            sin_family;   // e.g. AF_INET, AF_INET6
    unsigned short   sin_port;     // e.g. htons(3490)
    struct in_addr   sin_addr;     // see struct in_addr, below
    char             sin_zero[8];  // zero this if you want to
};

struct in_addr {
    unsigned long s_addr;          // load with inet_pton()
};

【问题讨论】:

  • 大概你是从 C++ 的角度谈论这个,因为 C 不会也永远不会关心。
  • 我最初的直觉反应是坚定的是的,但由于还没有发生解引用,并且bind() 的定义不是 C++ 程序的一部分,所以我是实际上并不是 100% 有信心。

标签: c++ network-programming


【解决方案1】:

许多 UNIX 网络基础都是建立在这些创造性的“滥用”结构之上的。这会使在非 C 代码中使用这些函数和结构变得相当困难,因为许多语言(如 C++)默认禁止此类任意重铸操作。

在 C++ 中,您需要处理这样一个事实,是的,从技术上讲,这些都不是有效的转换,但是 UNIX 网络规范已经存在了几十年并且是一种众所周知的商品。无论编译器坚持什么,您都可以对什么是有效的转换,什么不是有效的转换做出合理的假设。

与往常一样,您需要小心行事,尤其是在进行此类演员时。

【讨论】:

    猜你喜欢
    • 2020-04-11
    • 2020-02-08
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 2016-10-09
    相关资源
    最近更新 更多