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

时间:2022-05-26 02:14:29

I've got code that looks something like this, where addr is a sockaddr*:

我有代码看起来像这样,其中addr是一个sockaddr *:

struct sockaddr_in *sin = (struct sockaddr_in *) addr;
const char *IP=inet_ntoa(sin -> sin_addr);

I believe this is very typical code for using Berkeley sockets.

我相信这是使用Berkeley套接字的非常典型的代码。

However, when I compile this, I'm getting the following warning:
dereferencing pointer 'sin' does break strict anti-aliasing rules

但是,当我编译它时,我收到以下警告:取消引用指针'sin'会破坏严格的抗锯齿规则

Searching online, I find some discussion of the fact that the way I'm doing things is pretty typical, but this compiler warning also is pretty real and not a good thing.

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

What's the proper way to redo this code to fix the warning, and not just silence it?

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

4 个解决方案

#1


5  

I had the same issue - it looks like a bug in gcc.

我遇到了同样的问题 - 它看起来像是gcc中的一个bug。

I was able to get around it by using

我能够通过使用来绕过它

(*sin).sin_addr

instead of

sin->sin_addr

#2


2  

Yes, this is a know problem with gcc and sockets. The problem basically seems to be that the way this ip[46] stuff is designed is incompatible with the assumptions that the gcc people think they can deduce about aliasing of pointers.

是的,这是gcc和套接字的一个已知问题。问题基本上似乎是这个ip [46]设计的方式与gcc人们认为他们可以推断出指针别名的假设是不相容的。

I usually get away with this by first taking a pointer on the struct

我通常首先在结构上使用指针来逃避这一点

struct in_addr* act = &(sin->sin_addr);

and then using *act.

然后使用* act。

#3


1  

Depending on how you've used struct sockaddr, I think either your code is broken, or gcc is broken. struct sockaddr and struct sockaddr_in have a common initial element (sa_family/sin_family) so it does not violate aliasing rules if you have accessed only this element through both pointers; doing so is permitted by C99. Moreover, struct sockaddr has no other elements you're allowed to access. It's largely an opaque type for primitive socket address polymorphism. If you have been poking around at implementation-specific internals in struct sockaddr, or worse yet, if you declared a struct sockaddr object rather than just a pointer or performed copying between such objects, your code is broken. If you didn't, and gcc is giving a warning claiming you've broken aliasing rules, then gcc's warning generation is broken. I surely wouldn't be surprised if it's the latter.

根据你使用struct sockaddr的方式,我认为你的代码被破坏了,或者gcc被破坏了。 struct sockaddr和struct sockaddr_in有一个共同的初始元素(sa_family / sin_family),所以如果你只通过两个指针访问了这个元素,它就不会违反别名规则; C99允许这样做。而且,struct sockaddr没有其他允许访问的元素。它基本上是原始套接字地址多态的不透明类型。如果你一直在讨论struct sockaddr中特定于实现的内部,或者更糟糕的是,如果你声明了一个struct sockaddr对象而不仅仅是一个指针或者在这些对象之间执行了复制,那么你的代码就会被破坏。如果你没有,并且gcc发出警告声称你已经破坏了别名规则,那么gcc的警告生成就会被破坏。如果是后者,我肯定不会感到惊讶。

#4


-2  

If your header file and your compiler are both parts of the same C or C++ implementation, complain to your vendor and ask them to put a suitable #pragma in their header file to silence their compiler. As implementor, they're allowed to play games like that, as long as they provide a conforming implementation.

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

If your header file and your compiler came from two separate C or C++ implementations, you're lucky that things work as well as they do, and you have to solve it yourself.

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

#1


5  

I had the same issue - it looks like a bug in gcc.

我遇到了同样的问题 - 它看起来像是gcc中的一个bug。

I was able to get around it by using

我能够通过使用来绕过它

(*sin).sin_addr

instead of

sin->sin_addr

#2


2  

Yes, this is a know problem with gcc and sockets. The problem basically seems to be that the way this ip[46] stuff is designed is incompatible with the assumptions that the gcc people think they can deduce about aliasing of pointers.

是的,这是gcc和套接字的一个已知问题。问题基本上似乎是这个ip [46]设计的方式与gcc人们认为他们可以推断出指针别名的假设是不相容的。

I usually get away with this by first taking a pointer on the struct

我通常首先在结构上使用指针来逃避这一点

struct in_addr* act = &(sin->sin_addr);

and then using *act.

然后使用* act。

#3


1  

Depending on how you've used struct sockaddr, I think either your code is broken, or gcc is broken. struct sockaddr and struct sockaddr_in have a common initial element (sa_family/sin_family) so it does not violate aliasing rules if you have accessed only this element through both pointers; doing so is permitted by C99. Moreover, struct sockaddr has no other elements you're allowed to access. It's largely an opaque type for primitive socket address polymorphism. If you have been poking around at implementation-specific internals in struct sockaddr, or worse yet, if you declared a struct sockaddr object rather than just a pointer or performed copying between such objects, your code is broken. If you didn't, and gcc is giving a warning claiming you've broken aliasing rules, then gcc's warning generation is broken. I surely wouldn't be surprised if it's the latter.

根据你使用struct sockaddr的方式,我认为你的代码被破坏了,或者gcc被破坏了。 struct sockaddr和struct sockaddr_in有一个共同的初始元素(sa_family / sin_family),所以如果你只通过两个指针访问了这个元素,它就不会违反别名规则; C99允许这样做。而且,struct sockaddr没有其他允许访问的元素。它基本上是原始套接字地址多态的不透明类型。如果你一直在讨论struct sockaddr中特定于实现的内部,或者更糟糕的是,如果你声明了一个struct sockaddr对象而不仅仅是一个指针或者在这些对象之间执行了复制,那么你的代码就会被破坏。如果你没有,并且gcc发出警告声称你已经破坏了别名规则,那么gcc的警告生成就会被破坏。如果是后者,我肯定不会感到惊讶。

#4


-2  

If your header file and your compiler are both parts of the same C or C++ implementation, complain to your vendor and ask them to put a suitable #pragma in their header file to silence their compiler. As implementor, they're allowed to play games like that, as long as they provide a conforming implementation.

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

If your header file and your compiler came from two separate C or C++ implementations, you're lucky that things work as well as they do, and you have to solve it yourself.

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