简体   繁体   中英

What is the behaviour of a = b when a and b are unions?

As far as I understand the C and C++ standard regarding unions, it is technically undefined behaviour if I try to access a particular field of a union that is different to the field that was actually written to. Recently I have been reviewing some old code written by someone else that is similar to the following:

 union myunion {
     float myfloat;
     unsigned int myuint;
 };

 myunion a;
 a.myfloat = 1.01;

 myunion b = a;

in a nutshell, I am trying to find out if using the assignment operator on a union in this way is actually well defined behaviour. When I write code like this myself, I endeavour to store the type of the field actively used by a union instance and make sure that I only read or write this value. I am guessing that using the assignment operator above perhaps just results in a bitwise copy (since in this example the fields are of equal size) as stepping through the code in the debugger shows that this is what is happening. This code has been exhibiting subtle bugs so I am keen to find out if there is anything inherently risky in the sense of UB by directly assigning a union to another in this way.

As you would expect it to be. The behaviuor is well-defined.

b now has the same value as a, myfloat valued 1.01. Assignment is bitwise. If you want to compare a and b in a "safe" way you could do a bitwise comparison. (Using operator== on the float member isn't quite as safe, partly because it's UB if one of them doesn't actually contain a float, and partly of the issues of comparing floating point). Comparing for equality isn't actually automatically defined for unions so you would have to write an overload.

Unions always have only raw types in them that allow assignment to work. The only issue can be if the type can be a pointer and you manage that pointer somewhere. Then if you have two instances of your union holding this pointer you have to be careful. (However this would apply too if you even have a regular variable that contains a pointer).

In pre-C++11, union could only contain PODs (or something similar)—the restrictions were so designed that a bitwise copy would work. In C++11, some of the restrictions have been lifted, but if you violate the old restrictions, copy and assignment are deleted (unless you define the operators yourself).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM