首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >这个联合是否违反了严格的别名?那么浮点寄存器呢?

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

Stack Overflow用户
提问于 2012-09-06 09:32:14
回答 2查看 260关注 0票数 2
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
union
{
    Uint32 Integer;
    Float32 Real;
} Field;    

我必须使用这个联合来实现一个小小的IEEE技巧,这是否打破了严格的别名?GCC没有抛出任何警告(尝试了GCC 4.5和4.6,即使有学究的严格别名,但据我所知,GCC不是很好捕捉严格的别名规则违规(许多假阳性/阴性)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Field A;
A.Integer = (Value1 & B) || Value2;
return A.Real;

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

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

上面的代码并不是一个优化,所以不要因为滥用优化而贬低我,上面的代码是我获得某个结果的最简单的方法(幸运的是,在我的例子中,最简单的方法似乎也是最快的!),如果结果不安全,那么我将使用较慢的方法。

提前感谢

EN

回答 2

Stack Overflow用户

发布于 2012-09-25 17:35:18

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

因此,最有可能破坏这一点的方式是优化器决定从联合中删除读取,因为它没有定义的值。然而,大多数C-and-C++编译器可能会给你提供C行为,因为他们无论如何都需要支持C行为。

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

票数 1
EN

Stack Overflow用户

发布于 2012-09-25 17:04:20

它是UB (但不需要严格的别名)。此外,uniond数据总是通过实现存储在内存中,否则将需要知道源数据来自哪个寄存器,这意味着知道源类型。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12297049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文