https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86259
--- Comment #23 from Davin McCall <davmac at davmac dot org> --- (In reply to Martin Sebor from comment #22) > The test cases in this report are variations on this theme. [...] Ok, except that the one I posted in comment #21 specifically copies the string into a union member which is long enough to contain it, and while it takes the address of a subobject from the other union member, it does so while that member is active, and it casts to uintptr_t before subtracting the offset (so as to obtain a pointer to the containing object in a way that doesn't involve advancing a pointer beyond the bounds of the object it points into). It even casts this back to the union type before casting to (char *) again. At that stage it either: - points at the union object itself and its active member, which is a char[12], or - points at the union object but not its active member - points at the union object (and possibly its active member) but dereference is illegal due to provenance rules. The 3rd case would be greatly disturbing to myself and, I think, to many others; it would mean that you cannot meaningfully obtain a pointer to a containing object from a contained member other than the first one. The 1st case would mean that GCC is in error in compiling that code, since it gives the wrong result. Only the 2nd case avoids both those issues, but only if we allow that strlen on (part of) a non-char[] object has undefined behaviour even if the relevant portion of that object contains a suitably-sized char[] as a subobject in the relevant range. That seems tenuous and certainly not directly supported by the wording of the current specification, unless I've missed something.