解除引用指针确实会破坏使用Berkeley套接字的严格抗锯齿规则

时间:2010-08-12 05:09:25

标签: c compiler-warnings berkeley-sockets

我的代码看起来像这样,其中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

在网上搜索,我发现一些关于我正在做事的方式非常典型的事实的讨论,但这个编译器警告也非常真实而且不是一件好事。

重做此代码以修复警告的正确方法是什么,而不仅仅是让它静音?

4 个答案:

答案 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 sockaddrstruct sockaddr_in有一个共同的初始元素(sa_family / sin_family),因此如果您只通过两个指针访问了这个元素,它就不会违反别名规则; C99允许这样做。此外,struct sockaddr没有您允许访问的其他元素。它主要是原始套接字地址多态的不透明类型。如果您在struct sockaddr中一直在寻找特定于实现的内部,或者更糟糕的是,如果您声明了struct sockaddr对象而不仅仅是指针或在这些对象之间执行了复制,那么您的代码就会被破坏。如果你没有,并且gcc发出警告声称你已经破坏了别名规则,那么gcc的警告生成就会被破坏。如果是后者,我肯定不会感到惊讶。

答案 3 :(得分:-2)

如果您的头文件和编译器都是相同的C或C ++实现的一部分,请向您的供应商抱怨并要求他们在其头文件中放置一个合适的#pragma以使其编译器静音。作为实现者,只要他们提供一致的实现,他们就可以玩这样的游戏。

如果您的头文件和编译器来自两个独立的C或C ++实现,那么您很幸运,事情和它们一样有效,您必须自己解决它。