什么是 C 中的“陷阱表示”(一些示例可能会有所帮助)?这适用于 C++ 吗?
鉴于此代码…
float f=3.5;
int *pi = (int*)&f;
...并假设 `sizeof(int) == sizeof(float)` ,做 `f` 和 `*pi` 具有相同的二进制表示/模式?
原文由 Burt 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.5k 阅读
3 回答477 阅读✓ 已解决
unsigned char
(6.2.6.1p5, 6.2.6.2p1)。该标准给出了两个假设的陷阱表示示例,它们都不对应任何实际 CPU 多年来所做的任何事情,因此我不会将您与它们混淆。陷阱表示的一个 很好 的例子(也是您可能遇到的任何 CPU 上 唯一 有资格作为硬件级陷阱表示的东西)是浮点类型的信号 NaN。 C99 附录 F(第 2.1 节)明确未定义信号 NaN 的行为,尽管 IEC 60559 详细说明了它们的行为。
值得一提的是,虽然指针类型允许 有 陷阱表示,但空指针 不是 陷阱表示。空指针只有在被取消引用或偏移时才会导致未定义的行为;对它们的其他操作(最重要的是,比较和复制)是明确定义的。如果仅使用具有陷阱表示的类型 读取 陷阱表示,则会导致未定义的行为。 ( 无效 但非空指针是否或应该被视为陷阱表示是一个争论的主题。CPU 不会那样对待它们,但编译器可能会。)
float
转换为int
具有相同的表示形式(假设,如你所说,sizeof(float) == sizeof(int)
)此代码在 C99 中具有 _未指定_(不是未定义)的行为,这基本上意味着标准没有定义生成 _的整数值_,但是您确实得到 了一些 有效的整数值,它不是陷阱表示,并且不允许编译器优化假设你没有这样做。 (第 6.2.6.1 节,第 7 段。我的 C99 副本可能包括技术勘误——我记得这在原始出版物 中 未定义,但在 TC 中更改为未指定。)