首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从sockaddr *到sockaddr_in *的转换增加了所需的对齐

从sockaddr *到sockaddr_in *的转换增加了所需的对齐
EN

Stack Overflow用户
提问于 2016-02-22 10:59:34
回答 2查看 2.7K关注 0票数 7

当我处理一些代码时,编译器会产生这个警告,这些代码看起来像-

代码语言:javascript
复制
....

for(p = res; p != NULL; p = p->ai_next) {
    void *addr;
    std::string ipVer = "IPv0";

    if(p->ai_family == AF_INET) {
        ipVer                    = "IPv4";
        struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
        addr                     = &(ipv4->sin_addr);
    }

    else {
        ipVer                     = "IPv6";
        struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
        addr                      = &(ipv6->sin6_addr);
    }
....
}

其中p = res的类型为struct addrinfo,生成警告的类型为sockaddr_insockaddr_in6。警告来自声明:

  • struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
  • struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;

我只想知道是什么引起了这一警告,如果这不是正确的做法,我还能做些什么来纠正它。我能用一下static_cast / dynamic_cast / reinterpret_cast吗?

确切的警告是- cast from 'struct sockaddr *' to 'struct sockaddr_in *' increases required alignment from 2 to 4

EN

回答 2

Stack Overflow用户

发布于 2016-02-22 13:12:21

好的,-Weverything支持了相当多的警告,其中一些已知会抛出不想要的警告。

在这里,您的代码触发了cast-align警告,这说明了

从..。敬..。增加所需的对齐。敬..。

这里是这样的,因为struct addr的对齐值只有2,而struct addr_in的对齐值是4。

但是you (以及getaddrinfo的程序员)知道指针p->ai_addr已经指向一个实际的struct addr_in,所以强制转换是有效的。

你可以:

  • 让警告开火,忽略它-毕竟这只是一个警告.
  • 使用-Wno-cast-align-Weverything之后保持沉默

我必须承认,我很少使用-Weverything,而且只使用-Wall

或者,如果您知道只使用CLang,则可以使用语用学解释只在这些行中打开警告()。

代码语言:javascript
复制
for(p = res; p != NULL; p = p->ai_next) {
    void *addr;
    std::string ipVer = "IPv0";

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcast-align"

    if(p->ai_family == AF_INET) {
        ipVer                    = "IPv4";
        struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
        addr                     = &(ipv4->sin_addr);
    }

    else {
        ipVer                     = "IPv6";
        struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
        addr                      = &(ipv6->sin6_addr);
    }
#pragma clang diagnostic pop

....
}
票数 6
EN

Stack Overflow用户

发布于 2017-12-09 11:03:03

来详细说明memcpy版本。我认为这是ARM所需要的,因为它不能有错误的数据。

我创建了一个仅仅包含前两个字段的结构(我只需要端口)

代码语言:javascript
复制
struct sockaddr_in_header {
    sa_family_t    sin_family; /* address family: AF_INET */
    in_port_t      sin_port;   /* port in network byte order */
};

然后,为了获得端口,我使用memcpy将数据移动到堆栈中。

代码语言:javascript
复制
struct sockaddr_in_header   sinh;
unsigned short              sin_port;

memcpy(&sinh, conn->local_sockaddr, sizeof(struct sockaddr_in_header));

并返回港口

代码语言:javascript
复制
sin_port = ntohs(sinh.sin_port);

这个答案实际上与使端口在Arm上有关。

在臂上

那些被认为是和这个问题相同的权力,但是我不想忽视警告。经验告诉我,这是个坏主意。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35551879

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档