【问题标题】:Trap Representation, unsigned char and IA64 NaT陷阱表示、无符号字符和 IA64 NaT
【发布时间】:2014-10-19 15:16:39
【问题描述】:

Source:Uninitialized garbage on ia64 can be deadly

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

NaT 位最常通过推测执行设置。那里 是 ia64 上的一种特殊形式的加载指令,它试图 从内存中加载值,但如果加载失败(因为内存 被调出或地址无效),然后而不是引发 页面错误,所发生的只是设置了 NaT 位,然后执行 继续。

所有对 NaT 的数学运算只是再次产生 NaT。

源文章继续解释了寄存器如何在推测加载期间最终具有 NaT 表示,并发表了以下评论:

如你所见,如果你有一个值为 NaT 的寄存器,而你有这么多 以错误的方式呼吸它(例如,尝试将其值保存到 内存),处理器将引发 STATUS_REG_NAT_CONSUMPTION 例外。

从其他堆栈溢出对 Trap 表示的答案看来,
“任何类型(无符号字符除外)都可能有陷阱表示”。

link 这么说

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

如果分配了这样一个寄存器(设置了 NaT 位的寄存器)来存储未初始化的 unsigned char(类似于下面缺陷报告中的代码片段),根据 ISO C11 是如何处理的?

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

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

如果左值指定一个自动存储持续时间的对象, 可以用寄存器存储类声明(从来没有它的 地址),并且该对象未初始化(未使用 初始化器,并且在 使用),行为未定义

“C1X 更改”部分缺陷报告末尾的上述添加是否处理这种情况?

defect_report

以下函数在 C90 下具有未定义的行为,但出现 严格遵守 C99

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

【问题讨论】:

  • @Hasturkun - 感谢编辑
  • TL;DR NaT 根本不是陷阱表示。它涉及一个硬件位,它将这个或那个告诉硬件;但该位不是所讨论的 type 的一部分。从硬件的角度来看,它属于特定的内存位置或寄存器,但就C而言,它不是一个位。就像可以通过算术运算翻转的溢出位不是任何 C 值的一部分一样。与 NaN 进行比较和对比。
  • @n.m - 有问题的缺陷报告似乎表明这是一个陷阱表示? “在某些硬件(例如 Itanium)上,一个 8 位值可能有多达 257 个不同的值(0-255 和一个“Not a Thing”值)。但是,c99 明确禁止无符号字符的这种值。”
  • DR 指出了一个明显的差异并试图以一种不必要的过于复杂的方式解决它。我看不出真正的差异。 256 是某个硬件寄存器可以保存的值,但它不是 unsigned char 类型的对象可以保存的值,因此不是该类型的陷阱表示。它是某个寄存器可以保存的值,仅此而已。您可以将 256 一个无符号字符放在同一个寄存器中这一事实不会使 256 成为该类型的成员。同样,与 NaN 进行比较和对比。

标签: c


【解决方案1】:

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

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

标准中关于陷阱表示的部分继续排除unsigned char 可以具有陷阱表示的可能性——但这并不重要。这里要注意的是,正如 DR 中的 Spring 2008 note 所提到的,从标准的角度来看,这实际上根本不需要涉及陷阱表示本身(它们只是 UB 导致你在金属上的问题)。问题实际上与未初始化的自动值有关。修改后的段落通过澄清 unsigned char 应该仅仅因为其类型特定属性的一个而被视为豁免于一般类型的 UB(而不是通过添加该属性更复杂)。

您可以想象,正如 NaT 位是 IA64 上整数的实现细节一样,没有陷阱表示是一般 C 类型家族中一种特定类型的“实现细节”。变量的实际类型次要于更一般的规则,即访问任何未初始化的变量是不安全的;该添加阐明了该优先级。

【讨论】:

  • 谢谢,为什么标准排除/保证填充没有陷阱表示?
  • 填充不能有陷阱表示,因为填充不是真正的数据?您不能自己访问它;您可以(如果复制)以字节形式访问它。
猜你喜欢
  • 2011-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-18
  • 1970-01-01
  • 2015-07-25
  • 2011-01-11
相关资源
最近更新 更多