Hello, I don't want to reopen the long-rumbling discussion about what gcc ought to /want/ to do; I'd just like to know if warning in this case is indeed what it wants to do. The standard definition of IN6_ARE_ADDR_EQUAL looks a bit like this:
#define IN6_ARE_ADDR_EQUAL(a, b) \ (((const uint32_t *)(a))[0] == ((const uint32_t *)(b))[0] \ && ((const uint32_t *)(a))[1] == ((const uint32_t *)(b))[1] \ && ((const uint32_t *)(a))[2] == ((const uint32_t *)(b))[2] \ && ((const uint32_t *)(a))[3] == ((const uint32_t *)(b))[3]) That's cygwin's, but glibc is roughly the same (modulo s/const/__const/g). Anyhow it gives a strict aliasing warning now, that it didn't used to in 4.3.4: reduced testcase is --------------------------------------------------------------------- $ cat walias1.c typedef unsigned char uint8_t; typedef unsigned int uint32_t; struct in6_addr { uint8_t __s6_addr[16]; }; static inline int address_in_use (unsigned char *a, struct in6_addr *in6) { if ((((const uint32_t *)(a))[0] == ((const uint32_t *)(in6->__s6_addr))[0] && ((const uint32_t *)(a))[1] == ((const uint32_t *)(in6->__s6_addr))[1] && ((const uint32_t *)(a))[2] == ((const uint32_t *)(in6->__s6_addr))[2] && ((const uint32_t *)(a))[3] == ((const uint32_t *)(in6->__s6_addr))[3])) return 1; return 0; } ad...@ubik /tmp/warning $ /usr/bin/gcc-4 -c walias1.c -Wstrict-aliasing -O2 ad...@ubik /tmp/warning $ gcc-4 -c walias1.c -Wstrict-aliasing -O2 walias1.c: In function 'address_in_use': walias1.c:14:3: warning: dereferencing type-punned pointer will break strict-aliasing rules --------------------------------------------------------------------- Is that really right? The type of the pointer (in6->__s6_addr) that we're casting is unsigned char *, so shouldn't it already alias everything anyway and dereferencing it be allowed, like it is for the casted (a)? I'll file a PR if so. (I can't pretend I find the language in the spec easy to follow.) cheers, DaveK