Does this union violate a strict pseudonym? What About Floating Point Registers

union
{
    Uint32 Integer;
    Float32 Real;
} Field;    

      

I have to use this union for a little IEEE trick, does this break strict alias? GCC does not throw any warnings (tried with GCC 4.5 and 4.6 even with pedantic strict alias, but as far as I know GCC is not very well versed with strict alias rules (lots of false positives / negatives).

Field A;
A.Integer = (Value1 & B) || Value2;
return A.Real;

      

This snippet I'm currently using seems to work correctly without warning, but there could possibly be side effects or undefined behavior with certain compiler optimizations. So if this piece of code might be unsafe under certain conditions, I'll use some effort to remove it.

Also my guess is that this piece of code will need to move data from standard registers to floating point registers on most modern processors (this is just interesting), including some extra loops related to older processors, right?

The above code is not intended to be an optimization, so just don't belittle me for overusing the optimization, the above code was the easiest way to get a certain result (and luckily the easiest way seems to be also the fastest in my case!) If the result is not may be safe, I will use more slowly.

Thank you in advance

+2


source to share


2 answers


Merge via union is defined in C, but has undefined behavior in C ++; undefined behavior is equivalent to what happens when reading from an uninitialized variable (lvalue-to-rvalue conversion).

Accordingly, the most likely way to break is that the optimizer has chosen to exclude the read from the union because it has no specific value. However, most C-and-C ++ compilers will most likely give you C behavior, as they should support that anyway.



The safe way for value aliases is through copying eg. std::memcpy

or std::copy(reinterpret_cast<char *>(...), ...)

. Alternatively, if you can compile your project in both C and C ++, you can move the merge code to the C source file and only compile that code as C.

+1


source


It is UB (but does not require strict aliases). Also, data union

d is always kept in memory by implementations, AFAIK, otherwise it would require knowing which register the original data is being registered from, which means knowing the source type.



0


source







All Articles