On 01/10/2010 10:30 AM, Andreas Schwab wrote: > Dave Korn <dave.korn.cyg...@googlemail.com> writes: > >> 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.) > > IIUC both accesses are actually wrong, but in the case of a there is no > information about the actual target type, so the compiler cannot > optimize. In both cases an object is accessed as type uint32_t, but the > effective type is different.
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; } Why do you say the effective type is different? As long as uint8_t is a character type and both *a and *in6->__s6_addr have been written as uint32_t, this looks legal. Andrew.