陷阱表示,unsigned char和IA64 NaT

时间:2014-10-19 15:16:39

标签: c

Source:Uninitialized garbage on ia64 can be deadly

  

在ia64上,每个64位寄存器实际上是65位。额外的一点   被称为" NaT"代表"不代表"。该位设置为   寄存器不包含有效值。把它想象成   浮点NaN的整数版本。

     

NaT位最常见于推测执行。那里   是ia64上一种特殊形式的加载指令   从内存加载值,但如果加载失败(因为内存   被分页或地址无效),而不是提出一个   页面错误,所有发生的事情是NaT位被设置和执行   继续进行。

     

NaT的所有数学运算都会再次产生NaT。

源文章接着解释了在推测加载期间寄存器如何最终具有NaT表示并发出以下注释:

  

你知道,如果你有一个价值为NaT的寄存器,你就是这么多   以错误的方式呼吸它(例如,尝试将其值保存到   内存),处理器将引发STATUS_REG_NAT_CONSUMPTION   异常。

从pp表示的其他堆栈溢出答案中可以看出, "任何类型(unsigned char除外)都可能有陷阱表示"。

link表示

  

标准对访问未初始化的唯一保证   数据是unsigned char类型没有陷阱表示,和   填充没有陷阱表示。

如果这样的寄存器(具有NaT位设置的寄存器)被分配用于存储未初始化的无符号字符(类似于下面的缺陷报告中的代码片段),那么如何根据ISO C11处理它?<​​/ p>

下面的缺陷报告是否指向同一问题,是否在ISO C11中得到纠正?

如果不是如何处理这种特殊情况?

  

如果左值指定一个自动存储持续时间的对象   本来可以用寄存器存储类声明(从来没有它的   地址被取消),该对象未初始化(未声明为   初始化程序,并且之前没有执行任何赋值   使用),行为未定义

在缺陷报告的最后添加上面的#34;更改为C1X&#34;处理这种情况?

defect_report

  

以下功能在C90下具有未定义的行为,但会出现   根据C99严格遵守

  int foo(void) {
      unsigned char uc;
      return uc + 1 >= 0;
  }

1 个答案:

答案 0 :(得分:4)

首先,如果您还没有亲眼看到它,您可以从heresee also)获取C11标准的最终草稿。

DR中的文本确实已添加到第6.3.2.1节p2中,这使得代码根据C11未定义。

标准中关于陷阱表示的部分继续排除unsigned char可以有陷阱表示的可能性 - 但这无关紧要。这里需要注意的是,正如DR提到的2008年春季记录所提到的那样,从标准的角度来看,这实际上根本不需要涉及陷阱表示(它们只是UB可能引起的一种机制)金属上的问题)。问题实际上是关于未初始化的自动值;修改后的段落通过澄清unsigned char 仅仅因为一个类型特定属性而被视为免除一般类型的UB而解决了这个问题(不是通过为该属性添加更多复杂性。)

你可以想象,就像NaT位是IA64上整数的实现细节一样,陷阱表示的缺失是C类型的一般族中一种特定类型的“实现细节”。变量的实际类型是次要的一般规则,您不应该感到安全访问未初始化的任何变量;添加澄清了优先权。