TLDR:此警告并不表示代码中存在错误,但您可以通过使用poper c reinterpret_cast来避免它(感谢@Kurt Stutsman).
说明:
警告原因:
> sockaddr由无符号短(通常为16位)和char数组组成,因此其对齐要求为2.
> sockaddr_in包含(除其他外)一个结构in_addr,其对齐要求为4,这反过来意味着sockaddr_in也必须与4字节边界对齐.
因此,将任意sockaddr *转换为sockaddr_in *会更改对齐要求,并且通过新指针访问对象甚至会违反别名规则并导致未定义的行为.
为什么你可以忽略它:
在您的情况下,对象p-> ai_addr指向,最有可能是sockaddr_in或sockaddr_in6对象(通过检查ai_family确定),因此操作是安全的.但是,编译器不知道并生成警告.
它与使用static_cast将指向基类的指针强制转换为指向派生类的指针基本相同 – 在一般情况下它是不安全的,但如果你知道外部的正确动态类型,它就是明确定义的.
解:
我不知道一个干净的方法(除了抑制警告),这通常是由-Weverything启用的警告.您可以将p-> ai_addr指向的对象逐字节复制到相应类型的对象,但随后您可能(很可能)不再像以前那样使用addr,因为它现在指向不同的(例如本地)变量.
– 无论如何,我不会用我常用的版本,因为它会增加太多噪音,但如果你想保留它,@ Kurt Stutsman在评论中提到了一个很好的解决方案:
clang(g在任何情况下都不发出警告)不发出警告,如果你使用reinterpret_cast代替c样式演员(你不应该使用它),尽管两者都有(在这种情况下)相同的功能.也许是因为reinterpret_cast明确告诉编译器:“相信我,我知道,我在做什么”.
旁边注意:在c代码中,您不需要struct关键字.