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