是使用未定义的任何不确定值还是仅存储在具有自动存储的对象中的值?

根据C99 J.2,在以下情况下行为未定义:

具有自动存储持续时间的对象的值在不确定时使用

那么对象具有不确定值的所有其他情况呢? 如果我们使用它们,我们是否也总是调用UB? 或者我们只在它们包含陷阱表示时调用UB?

例子包括:

  • 使用malloc分配的对象的值(7.20.3.3p2)
  • [存储在非自动存储器中]调用fclose后的FILE* (7.19.3p4)
  • [存储在非自动存储器中]一个指针后free调用它(6.2.4p2)

…等等。


我已将C99用于我的参考文献,但您可以在答案中自由引用C99或C11。

我在这里使用C11修订版:

标准的定义是:

不确定的价值

要么是未指定的值,要么是陷阱表示

陷阱表示

一个对象表示,不需要表示对象类型的值

未指明的价值

未指定相关类型的有效值 ,其中本国际标准不对任何情况下选择的值施加任何要求


未指定的值是相关类型的有效值,因此不会导致未定义的行为。 使用陷阱表示将。


但是为什么标准中存在这样的措辞,摘录使编译器能够发出诊断信息,或者拒绝使用未初始化的局部变量值但仍然符合标准的程序; 因为有些类型可以说它们不能在内存中包含陷阱表示,所以它们在不确定状态下总是具有未指定的值 。 这适用于例如unsigned char 。 并且由于使用未指定的值没有未定义的行为,因此标准不允许拒绝这样的程序。

另外,假设一个unsigned char通常没有陷阱表示……除了IIRC有计算机体系结构,其中寄存器可以设置为“未初始化”,并且从这种体系结构中的寄存器读取将触发故障。 因此,即使unsigned char在内存中实际上没有陷阱表示,在这种架构上,如果它具有自动存储持续时间并且编译器决定将其存储在寄存器中并且它仍然存在,则它将导致100%概率的硬件故障在通话时未初始化。