这种联合会破坏严格的别名吗?浮点寄存器呢?
Does this union break strict aliasing? What about floating point registers
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
或std::copy(reinterpret_cast<char *>(...), ...)
. 或者,如果可以同时使用 C 和 C++ 编译项目,则可以将联合别名代码移动到 C 源文件,并将该代码编译为 C。
UB(但不需要严格的别名(。此外,union
d数据始终由实现AFAIK存储在内存中,否则需要知道源数据来自哪个寄存器,这意味着知道源类型。
- 本质:使用__128寄存器
- 将寄存器设计成可由C和C++访问的外设的最佳实践
- 在模拟器中使用并集来模拟CPU寄存器有多合适
- 使用英特尔 PIN 修改寄存器
- AVX 指令中寄存器和指针之间的客观差异
- 如何确定我的处理器有多少个 AVX 寄存器?
- 除非使用某些寄存器,否则函数挂钩会崩溃
- 寄存器上的管道计算
- 其中关于内存和寄存器的左值和右值
- 有没有办法强制C++编译器将变量存储在寄存器中?
- "变量":函数中函数作用域不允许初始化的自动或寄存器变量'naked'
- Atmel Studio:返回一个包含数组的寄存器
- 使用 googletest 测试嵌入式C++代码时处理外设寄存器的重复符号
- 移位寄存器74HC595输出电流
- 超过255的Modbus寄存器无法访问SimpleModbus
- 如何在程序集函数中将元素数组作为参数传递时转发 ARM 寄存器的地址指针
- xmm 寄存器中的__m128何时?
- 是否可以在 GCC 中使用带有 C++17 的显式寄存器变量?
- 处理器寄存器的大小是多少,有多少个处理器寄存器?
- 这种联合会破坏严格的别名吗?浮点寄存器呢?