我的代码看起来像这样,其中addr是一个sockaddr *:
struct sockaddr_in *sin = (struct sockaddr_in *) addr;
const char *IP=inet_ntoa(sin -> sin_addr);
我相信这是使用Berkeley套接字的非常典型的代码。
但是,当我编译它时,我收到以下警告:
dereferencing pointer 'sin' does break strict anti-aliasing rules
在网上搜索,我发现一些关于我正在做事的方式非常典型的事实的讨论,但这个编译器警告也非常真实而且不是一件好事。
重做此代码以修复警告的正确方法是什么,而不仅仅是让它静音?
答案 0 :(得分:5)
我有同样的问题 - 它看起来像是gcc中的一个错误。
我能够通过使用
解决这个问题(*sin).sin_addr
而不是
sin->sin_addr
答案 1 :(得分:2)
是的,这是gcc和套接字的已知问题。问题基本上似乎是这个ip [46]设计的方式与gcc人们认为他们可以推断出指针别名的假设是不相容的。
我通常首先在struct
struct in_addr* act = &(sin->sin_addr);
然后使用*act
。
答案 2 :(得分:1)
根据您使用struct sockaddr
的方式,我认为您的代码已损坏,或者gcc已损坏。 struct sockaddr
和struct sockaddr_in
有一个共同的初始元素(sa_family
/ sin_family
),因此如果您只通过两个指针访问了这个元素,它就不会违反别名规则; C99允许这样做。此外,struct sockaddr
没有您允许访问的其他元素。它主要是原始套接字地址多态的不透明类型。如果您在struct sockaddr
中一直在寻找特定于实现的内部,或者更糟糕的是,如果您声明了struct sockaddr
对象而不仅仅是指针或在这些对象之间执行了复制,那么您的代码就会被破坏。如果你没有,并且gcc发出警告声称你已经破坏了别名规则,那么gcc的警告生成就会被破坏。如果是后者,我肯定不会感到惊讶。
答案 3 :(得分:-2)
如果您的头文件和编译器都是相同的C或C ++实现的一部分,请向您的供应商抱怨并要求他们在其头文件中放置一个合适的#pragma以使其编译器静音。作为实现者,只要他们提供一致的实现,他们就可以玩这样的游戏。
如果您的头文件和编译器来自两个独立的C或C ++实现,那么您很幸运,事情和它们一样有效,您必须自己解决它。