Source:Uninitialized garbage on ia64 can be deadly陷阱表示,无符号的字符和IA64的NaT
在IA64中,每个64位寄存器实际上是65位。额外的位 被称为“NaT”,代表“不是一件事”。该位在 寄存器不包含有效值时置位。把它看作浮点数NaN的整数版本 。
NaT位最常从推测执行中设置。其中 是ia64上的一种特殊的加载指令形式,它试图从内存中加载值,但是如果加载失败(因为内存 被换页或地址无效),则不会产生页面错误 ,所发生的只是NaT位被设置,并且执行 继续。
对NaT的所有数学运算只是再次产生NaT。
源文章接着解释寄存器如何能最终有投机性的加载过程中在NAT表示,并提出以下备注:
对于你看,如果你有一个寄存器的值是NaT和你这么多的呼吸错误的方式(例如,尝试将其值存储到 内存),处理器将引发一个STATUS_REG_NAT_CONSUMPTION 异常。
似乎从其它堆栈溢出的答案是,
“任何类型的(除了无符号字符)可以具有陷阱的表示”陷阱表示。
这link说
的唯一保证标准给出有关访问未初始化 数据是unsigned char类型有没有陷阱交涉,并 是填充有没有陷阱表示。
如果这样的寄存器(具有NAT的寄存器位被设置)被分配用于存储一个未初始化的无符号字符(类似于从下面的缺陷报告的代码片段),这是怎么根据ISO C11处理?
下面的缺陷报告是否指向相同的问题,并在ISO C11中纠正?
如果不是这个特殊情况如何处理?
如果左值指定该 可能已被宣布与寄存器存储自动存储时间的对象(从来没有考虑其 地址),而该对象未初始化(不与 初始申报,并没有分配到它已被执行之前 使用),其行为是未定义
确实上述加成在节“为C1X变化”缺陷报告末尾处理这种情况?
了以下功能未定义C90下的行为,但似乎 要严格C99下符合
int foo(void) {
unsigned char uc;
return uc + 1 >= 0;
}
@Hasturkun - 感谢编辑 – 2014-10-19 15:28:35
TL; DR NaT根本不是陷阱表示。它涉及一个硬件位,告诉硬件或硬件;但该位不是*类型*的一部分。它从硬件的角度来看属于一个特定的内存位置或寄存器,但就C而言它并没有多大意义。就像可以通过算术运算翻转的溢出位不是任何C值的一部分。与NaN进行比较和对比。 – 2014-10-20 05:40:11
@ n.m - 有问题的缺陷报告似乎表明这是一个陷阱表示? “在某些硬件(例如Itanium)上,一个8位值可能有多达257个不同的值(0-255和”Not a Thing“值)。但是,c99明确禁止这样的值作为无符号字符。 – 2014-10-20 06:02:59