4 ms·
What part of the standard should I read to come to the conclusion that type punning with unions is undefined behavior? C99 and C11 both explicitly mention that
by boomlinde 8y ago
What part of the standard should I read to come to the conclusion that type punning with unions is undefined behavior? C99 and C11 both explicitly mention that it's not, but maybe you're talking C89/C90?
IMO there are 4 highly relevant paragraphs in C99:
6.2.6.1: When a value is stored in an object of structure or union type, including in a member object, the bytes of the object representation that correspond to any padding bytes take unspecified values.
6.2.6.1: When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values
6.5.2.3 DR283) If the member used to access the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning").
6.7.2.1: A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit-field, then to the unit in which it resides), and vice versa.
None of this implies that unions can't be used for type punning. What it does imply is that reading from a larger member of the union than you last wrote to will leave you with an unspecified value.
- acqq 8y agoI think the clang and gcc contributors consider all this in combination with “strict aliasing” and “type” consistency attitude effectively if you just wrote a double to a union member, you can’t expect that reading integer from the same union has any meaning at all so they optimized that away “per standard”. To come to that, it’s not what is explicitly written when you do a keyword search for “union” but what is not said that it “must work” in spite of other “must work” and “undefined” standard statements. But ask them for the details, I’m just following the topic and have no active involvement.
- boomlinde 8y ago> if you just wrote a double to a union member, you can’t expect that reading integer from the same union has any meaning at all so they optimized that away “per standard”. gcc 4.9.2 for sure does not (-O3 -fstrict-aliasing). Not sure what clang does, but I'd be surprised if it ignores the standard. The standard makes it pretty clear what meaning it will have. Sure, gcc and clang maintainers may seem to read the standards like a lawyer looking to void a contract, but in this case it is actually very clear what they should do. > what is not said that it “must work” in spite of other “must work” and “undefined” standard statements. The standard makes it clear how to deal with the semantics: "In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object)." Only constraints directly use "shall"/"shall not" type language, but the expressions should still be evaluated as specified by the semantics.
- acqq 8y agoGoogling I've found for example this: “GNU extensions to standard C++ (and to C90) do explicitly allow type-punning with unions. Other compilers that don't support GNU extensions may also support union type-punning, but it's not part of the base language standard.” Also, apparently in C99 one relevant statement was: “The value of a union member other than the last one stored into [is unspecified]” https://stackoverflow.com/questions/25664848/unions-and-type-punning https://stackoverflow.com/questions/25664848/unions-and-type... Note: In case it's not obvious, I, personally, believe that, at least, using unions for type-punning has to exist and should be explicitly supported in the standards too. And that the compiler contributors should not produce practically unusable results even when some standard is wrong (for common use) or unclear. But the quotes like the above give a hint on which basis some try to cling to bad approaches in this special case. In other cases it's probably even harder to avoid unwanted results.