I have a multithreaded application that stores data as an array of instances of the following union
union unMember {
float fData;
unsigned int uiData;
};
The object that stores this array knows what type the data in the union is and so I dont have problems with UB when retrieving the correct type. However in other parts of the program, I need to test equality between 2 instances of these unions and in this part of the code the true internal data type is not known. The result of this is that I can’t test equality of the union using this kind of approach
unMember un1;
unMember un2;
if (un1 == un2) {
// do stuff
}
as I get compiler errors. As such I am simply to compare the float part of the union
if (un1.fData == un2.fData) {
// compiles but is it valid?
}
Now given that I have read about it being UB accessing any part of a union that was not the part that was last written to (that is cumbersomely written but I can think of no more articulate way to say this) I am wondering if the code above is a valid way to check equality of my union instances??
This has made me realise that internally I have no idea how unions really work. I had assumed that data was simply stored as a bit pattern and that you could interpret that in whatever way you like depending on the types listed in the union. If this is not the case, what is a safe/correct way to test equality of 2 instances of a union?
Finally, my application is written in C++ but I realise that unions are also part of C, so is there any difference in how they are treated by the 2 languages?
In general, you need to prepend some kind of indicator of the current union type:
Then:
Anyway, the syntax
which does compile and is valid, might not work for two reasons. One is that, as you said, maybe un2 contains an integer and not a floating point. But in that case the equality test will normally fail anyway. The second is that both structures hold a floating point, and they represent the same number with a slight machine error. Then the test will tell you the numbers are different (bit by bit they are), while their “meaning” is the same.
Floating points are usually compared like
to avoid this pitfall.