Does this union break strict aliasing? What about floating point registers

我是研究僧i 提交于 2019-12-02 02:26:14

问题


union
{
    Uint32 Integer;
    Float32 Real;
} Field;    

I have to use that union for a little IEEE trick, does that break strict aliasing? GCC is not throwing any warning(tried with GCC 4.5 and 4.6 even with pedantic strict aliasing, but As Far As I Know, GCC is not very good catching strict aliasing rules infringiments (lots of false positives/negatives).

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

That's the snippet I'm currently using, it seems working correctly without any warning, but maybe there can be side effects or undefined behaviours with certain compilers optimizations. So If that piece of code can be unsafe under certain conditions I will use some effort to remove that.

Also I assume that this piece of code will require moving data from standard registers to floating pointing registers on most modern CPUs (just curious about that), involving some extra cycles respect to older CPUs, correct?

The code above don't intend to be an optimization, so just don't derogate me for abusing optimizing, the code above was the simplest way for me to obtain a certain result (and luckily the simplest way seems also to be the fastest in my case!), if the result can't be safe, then I'll use a slower way.

Thanks in advance


回答1:


Aliasing via a union is defined in C but has undefined behaviour in C++; the undefined behaviour is equivalent to that which occurs when reading from an uninitialized variable (a lvalue-to-rvalue conversion).

Accordingly, the most likely way this would break is in the optimiser deciding to eliminate the read from the union, as it does not have a defined value. However, most C-and-C++ compilers are likely to give you the C behaviour as they need to support that anyway.

The safe way to alias the values is via bytewise copy e.g. std::memcpy or std::copy(reinterpret_cast<char *>(...), ...). Alternatively, if you can compile your project in both C and C++ you could move the union aliasing code to a C source file and compile just that code as C.




回答2:


It is UB (but doesn't require strict aliasing). Also, uniond data is always stored in memory by implementations, AFAIK, else would require knowing which register the source data came from, which means knowing the source type.



来源:https://stackoverflow.com/questions/12297049/does-this-union-break-strict-aliasing-what-about-floating-point-registers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!