首页 > 解决方案 > 关于“具有多个对象表示的对象”的未指定行为

问题描述

仍在与 C (C99) 未定义和未指定的行为作斗争。

这次是以下未指定行为(附件 J.1):

将值存储在具有多个该值的对象表示的对象中时使用的表示 (6.2.6.1)。

相应的 6.2.6.1 节指出:

如果将运算符应用于具有多个对象表示的值,则使用哪个对象表示不应影响结果的值43)。如果一个值使用具有多个对象表示的类型存储在一个对象中,则未指定使用哪种表示,但不应生成陷阱表示。

附注 43:

当对象作为 type 的对象访问时,具有相同有效类型的对象可能具有相同的值xy但在其他上下文中具有不同的值。特别是,如果为 type 定义,则并不意味着。此外,并不一定意味着 和具有相同的价值;对类型值的其他操作可能会区分它们。TT==Tx == ymemcmp(&x, &y, sizeof(T)) == 0x == yxyT

我什至不明白什么是具有多个对象表示的值。例如,它是否与 0(负零和正零)的浮点表示有关?

标签: cc99unspecified-behavior

解决方案


这种语言的大部分内容是 C 标准,它非常适合在 Burroughs B 系列大型机上继续使用(AFAICT 是唯一幸存的补码架构)。除非您必须使用这些或某些不常见的微控制器,或者您正在认真进行逆向计算,否则您可以放心地假设整数类型的每个值只有一个对象表示,并且它们没有填充位。您还可以安全地假设所有整数类型都没有陷阱表示,除了您必须采用 J.2 的这一行

[如果 ... 行为未定义]具有自动存储持续时间的对象的值在不确定时被使用

好像它是规范的,好像划掉的词不存在。(仔细阅读实际的规范文本并不支持该规则,但它仍然是当前所有优化编译器所采用的规则。)

在现代的、非异国情调的实现中,可以对一个值具有多个对象表示的类型的具体示例包括:

  • _Bool_Bool:用整数值的表示而不是适当大小的 0 或 1覆盖对象的效果是未指定的。

  • 指针类型:一些架构忽略指向最小对齐大于 1 的类型的指针的低位(例如(int*)0x8000_0000(int*)0x8000_0001可能被视为引用同一int对象;这是一个有意的硬件特性,便于使用标记指针)

  • 浮点类型:IEC 60559 允许硬件对 NaN 的所有许多表示进行相同的处理(并且可能将它们压缩在一起)。(注意:+0 和 -0 是 IEEE 浮点中的不同值,而不是相同值的不同表示。)

这些也是在现代实现中可以具有陷阱表示的标量类型。特别是,附件 F 明确声明了未定义信号 NaN 的行为,即使它在 IEC 60559 的抽象实现中已明确定义。


推荐阅读