Eric Botcazou wrote: >> The aliasing rules treat "char" specially because char is a bit like a >> "poor main's void". > > Not symmetrically though, only for the type of the lvalue expression used to > access the object (C99 6.5.7). >
Ok. So if I had four ints, and I wanted to cast the pointers to char and compare them as 16 chars, that would be OK, because the chars would alias the ints; but in this case, where they started as chars and I cast them to ints, those ints don't alias against the original chars. Is that an accurate precis? Andreas, you wrote: "Aliasing is not symmetric". To be precise, we're saying it's not commutative here; that (A aliases B) does not imply (B aliases A)? I don't think I've ever heard it expressed that explicitly before. So, the only way to do this trick nowadays is to use a union, right? > union u > { > uint8_t aschars[16]; > uint32_t aslongs[4]; > }; > > static inline int > address_in_use2 (unsigned char *a, struct in6_addr *in6) > { > union u *u1 = (union u *)in6.__s6_addr; > union u *u2 = (union u *)a; > > if ((u1->aslongs[0] == u2->aslongs[0]) > && (u1->aslongs[1] == u2->aslongs[1]) > && (u1->aslongs[2] == u2->aslongs[2]) > && (u1->aslongs[3] == u2->aslongs[3])) > return 1; > > return 0; > } ... and this is allowed because I have cast the char pointers into pointers to "an aggregate or union type that includes one of the aforementioned types", and the object in question currently has no effective type because it was stored into by chars (when it was a char[] array in struct in6_addr) so the type of the lvalue when I dereference it is just "the type of the lvalue used for the access"? Also, that's getting kinda tricky to write in a macro, isn't it? I mean without having to use something highly gcc-specific like expression statements? cheers, DaveK