这个联合是否违反了严格的别名?浮点寄存器怎么样

2024-03-08

union
{
    Uint32 Integer;
    Float32 Real;
} Field;    

我必须使用该联合来实现一些 IEEE 技巧,这会破坏严格的别名吗? GCC 不会发出任何警告(即使使用迂腐的严格别名,也尝试过 GCC 4.5 和 4.6,但据我所知,GCC 并不能很好地捕获严格别名规则违规(大量误报/漏报)。

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

这是我当前正在使用的代码片段,它似乎工作正常,没有任何警告,但某些编译器优化可能会产生副作用或未定义的行为。因此,如果该代码在某些情况下可能不安全,我将尽力将其删除。

另外,我假设这段代码需要将数据从标准寄存器移动到大多数现代 CPU 上的浮点寄存器(只是对此感到好奇),这涉及到旧 CPU 的一些额外周期,对吗?

上面的代码无意进行优化,所以不要贬低我滥用优化,上面的代码是我获得特定结果的最简单方法(幸运的是,最简单的方法似乎也是最快的方法)我的情况!),如果结果不安全,那么我会使用较慢的方法。

提前致谢


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

因此,最有可能发生这种情况的方式是优化器决定消除从联合中的读取,因为它没有定义的值。然而,大多数 C 和 C++ 编译器可能会为您提供 C 行为,因为无论如何它们都需要支持该行为。

对值进行别名的安全方法是通过字节复制,例如std::memcpy or std::copy(reinterpret_cast<char *>(...), ...)。或者,如果您可以用 C 和 C++ 编译项目,则可以将联合别名代码移至 C 源文件,然后将该代码编译为 C。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

这个联合是否违反了严格的别名?浮点寄存器怎么样 的相关文章

随机推荐