是使用任何未定义的不确定值还是仅使用那些存储在具有自动存储功能的对象中的值?
Is using any indeterminate value undefined or just those stored in objects with automatic storage?
根据 C99 J.2,在以下情况下行为未定义:
The value of an object with automatic storage duration is used while it is indeterminate
对象具有不确定值的所有其他情况呢?如果我们使用它们,我们是否也总是调用 UB?还是仅当它们包含陷阱表示时我们才调用 UB?
示例包括:
- 使用
malloc
(7.20.3.3p2) 分配的对象的值
- [存储在非自动存储] a
FILE*
在调用fclose
之后 (7.19.3p4) - [存储在非自动存储中]调用
free
后的指针 (6.2.4p2)
...等等。
我使用 C99 作为参考,但请在您的回答中随意参考 C99 或 C11。
我这里使用的是 C11 版本:
标准中的定义是:
indeterminate value
either an unspecified value or a trap representation
trap representation
an object representation that need not represent a value of the object type
unspecified value
Unspecified valid value of the relevant type where this International Standard imposes no requirements on which value is chosen in any instance
未指定的值是相关类型的有效值,因此它不会导致未定义的行为。使用陷阱表示将。
但是标准中存在这种措辞的原因是摘录使编译器能够发出诊断,或者拒绝使用未初始化局部变量的值但仍保持标准兼容的程序;因为据说有些类型不能在内存中包含陷阱表示,所以它们总是在它们的未指定值不确定的状态。这适用于例如 unsigned char
。并且由于使用未指定的值没有未定义的行为,因此标准不允许拒绝这样的程序。
另外,说一个 unsigned char
通常没有陷阱表示...除了,IIRC 有一些计算机体系结构,其中寄存器可以设置为“未初始化”,并且从寄存器中读取这样的体系结构将触发故障。因此,即使 unsigned char
在内存中没有真正的陷阱表示,在这种架构上,如果它具有自动存储持续时间并且编译器决定将其存储在寄存器中,那么它会以 100% 的概率导致硬件故障,并且它在调用时仍未初始化。