In the comments of this answer it is said that it would be undefined behavior to split up an integer into their bytes using a union like follows. The code given at that place is similar though not identical to this, please give a note if have I changed undefined-behavior-relevant aspects of the code.
union addr {
uint8_t addr8[4];
uint32_t addr32;
};
Up to now I thought this would be a fine approach to do things like addr = {127, 0, 0, 1};
and get the corresponding uint32_t
in return. (I acknowledge that this may yield different results depending on the endianness of my system. The question however remains.)
Is this undefined behavior? If so, why? (I don't know what means What's UB in C++ is to access inactive union members.)
C99
C++03
However
Conclusion
uint8_t[4]
and uint32_t
are not the same type (I guess, a strict aliasing thing) (plus both not being POD-structs/union) the above is indeed UB?C++11
I don't know what means What's UB in C++ is to access inactive union members.
Basically what it means is that the only member you can read from a union without invoking undefined behavior is the last written one. In other words, if you write to addr32
, you can only read from addr32
, not addr8
and vice versa.
An example is also available here.
Edit: Since there has been much discussion if this is UB or not, consider the following (fully valid) C++11 example;
union olle {
std::string str;
std::wstring wstr;
};
Here you can definitely see that activating str and reading wstr may be a problem. You could see this as an extreme example since you even have to activate the member by doing a placement new, but the spec actually covers this case with no mention that it's to be considered a special case in other ways regarding active members.
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