union A{
int a;
int b;
};
int main(){
A u = {.a = 0};
int r = u.b; // #1 Is this UB?
}
[class.union] says
In a union, a non-static data member is active if its name refers to an object whose lifetime has begun and has not ended ([basic.life]). At most one of the non-static data members of an object of union type can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time.
In this example, only A::a is active, then [basic.life] p7 says
The program has undefined behavior if:
- the glvalue is used to access the object, or
#1 tries to access the object whose lifetime has not begun. Does this access cause UB, if it is, is this requirement too restrictive?
BTW, Does the C standard impose the same requirement in this example? Or, Does C have a looser requirement in this case?
In C standard, I find a note, which says
If the member used to read 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). This might be a non-value representation.
This means it is permitted in C. However, https://eel.is/c++draft/diff.iso
Subclause [diff.iso] lists the differences between C++ and ISO C, in addition to those listed above, by the chapters of this document.
does not point out the difference.
I think in C++ this is undefined behavior per the first standard quotation in the question itself: there is no exception there for the case of same types of data members.
And major compilers seem to agree with this reading, disallowing such code in constant expressions:
union A{
int a;
int b;
};
constexpr int f() {
A u = {.a = 0};
return u.b;
}
constexpr int x = f();
Online demo: https://gcc.godbolt.org/z/We4zYzdaa
Clang's error:
read of member 'b' of union with active member 'a' is not allowed in a constant expression
GCC's error:
accessing 'A::b' member instead of initialized 'A::a' member in constant expression
MSVC's error:
failure was caused by accessing a non-active member of a union
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With