Hi Vincent,
On Sat, May 14, 2016 at 07:08:12PM +0200, Vincent Bernat wrote:
> I think this is an aliasing problem. You cannot have two incompatible
> variables pointing at the same memory spot. It seems that now
> sockaddr_storage and sockaddr_in are not compatible anymore.
Here it's not an aliasing problem in my opinion since we build with
-fno-strict-aliasing for this reason. Also usually when gcc produces
an unexpected behaviour we at least have a corresponding warning, here
it simply produces bad code.
> #v+
> struct sockaddr_storage
> {
> __SOCKADDR_COMMON (ss_); /* Address family, etc. */
> __ss_aligntype __ss_align; /* Force desired alignment. */
> char __ss_padding[_SS_PADSIZE];
> };
>
> struct sockaddr_in
> {
> __SOCKADDR_COMMON (sin_);
> in_port_t sin_port; /* Port number. */
> struct in_addr sin_addr; /* Internet address. */
>
> /* Pad to size of `struct sockaddr'. */
> unsigned char sin_zero[sizeof (struct sockaddr) -
> __SOCKADDR_COMMON_SIZE -
> sizeof (in_port_t) -
> sizeof (struct in_addr)];
> };
> #v-
>
> If I introduce this type:
>
> #v+
> struct sockaddr_storage_universal {
> union {
> struct sockaddr_storage sas;
> struct sockaddr_in sai;
> struct sockaddr_in6 sai6;
> };
> };
> #v-
>
> This works when used in place of "struct sockaddr_storage".
This might be something we can switch to in the future to see if we can
remove -fno-strict-aliasing (but for how long?). The emitted code is
slightly better without it (less data reloads) and disabling aliasing
for the whole code just to satisfy a few places is a bit annoying.
> I see the
> glibc is using an union too instead of struct sockaddr or struct
> sockaddr_storage. man 7 socket still says to use struct
> sockaddr_storage.
Yes it depends a lot on the syscalls in fact :-/
> Searching a bit, there is this old question on StackOverflow:
>
> http://stackoverflow.com/questions/1429645/how-to-cast-sockaddr-storage-and-avoid-breaking-strict-aliasing-rules
Yep and on this one they were indeed trying *not* to have to use
-fno-strict-aliasing.
Thanks,
Willy