这个联合是否破坏严格的别名?什么浮点寄存器 [英] Does this union break strict aliasing? What about floating point registers

查看:226
本文介绍了这个联合是否破坏严格的别名?什么浮点寄存器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

union
{
    Uint32 Integer;
    Float32 Real;
} Field;    

我必须使用该联合作为一个小小的IEEE技巧,是否会破坏严格的别名? GCC不会抛出任何警告(尝试与GCC 4.5和4.6,即使有严格的严格别名,但是我知道,GCC是不是很好的捕捉严格的混叠规则的侵权(大量的假阳性/负面)。

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.

这段代码将需要将数据从标准寄存器移动到大多数现代CPU上的浮点指针寄存器(只是好奇),涉及到更老的CPU的一些额外的周期,是否正确?

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.

提前感谢

推荐答案

通过联合进行别名的定义在C中定义,但在C ++中有未定义的行为;未定义的行为等同于从未初始化的变量(一个左值到右值的转换)读取时发生的行为。

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).

因此,最有可能的方式是在优化器中决定从联合中消除读,因为它没有定义的值。然而,大多数C和C ++编译器很可能给你C的行为,因为他们需要支持。

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.

对值进行别名的安全方法是通过bytewise复制eg std :: memcpy std :: copy(reinterpret_cast< char *>(...),...)。或者,如果您可以在C和C ++中编译项目,您可以将联合别名代码移动到C源文件,并只将该代码编译为C.

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.

这篇关于这个联合是否破坏严格的别名?什么浮点寄存器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆