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

时间:2016-05-13 08:03:51

标签: c c99 undefined-behavior c11

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

  

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

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

示例包括:

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

......等等。

我已将C99用于我的推荐,但您可以在答案中参考C99或C11。

1 个答案:

答案 0 :(得分:2)

我在这里使用C11修订版:

标准的定义是:

  

不确定价值

     

未指定的值或陷阱表示

     

陷阱表示

     

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

     

未指定的值

     

本国际标准中没有规定的相关类型的未指定有效值   在任何情况下选择值的要求

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

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

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