【发布时间】:2021-09-11 18:27:49
【问题描述】:
引用 N4868 6.8.2 第 5 段:
宽度为 N 的无符号整数类型的每个值 x 都有唯一的表示...
值得注意的是,它避免指定“值表示”或“对象表示”,因此不清楚此处是否有意。
稍后(在实现定义行为的索引中),N4868 确实将指针和浮点类型的值表示称为实现定义,但非常明显地排除了整数类型。
鉴于此,我能想到四种可能的解释:
- 整数类型的值表示是唯一指定的
- 未指定整型的值表示
- 整数类型的值表示是实现定义的,但被错误地排除在上述索引之外
- 整数类型的值表示未定义
#1 似乎是不可能的,因为大端和小端架构都存在实现。
#3 似乎不太可能,因为索引中没有整数类型很明显,浮点和指针类型的实际文本都表明它们是实现定义的,而整数类型的文本很长避免指定值表示。
#2 是最有可能的解释,但值得注意的是,该标准经常将行为称为未指定,但这里没有这样说。除其他外,这意味着即使实际上并未如此调用,也可以未指定行为,这使得很难区分仅未指定的行为与标准未定义的行为根本没有定义它(而不是被称为“未定义的行为”)
#4 似乎很荒谬,因为该标准暗示所有类型(或至少是可简单复制的类型)都具有明确的(如果未指定)对象表示(以及扩展的值表示)。具体来说,6.7 第 4 段规定:
对于普通可复制类型,值表示是对象表示中的一组位 确定一个值,该值是实现定义的一组值的一个离散元素。
这似乎暗示了普通可复制类型(包括整数类型)的值表示是未指定的。
场景 #2 可能表明未能将表示称为“未指定”,因为我们在第 3 节的“未定义行为”定义下有注释:“当本文档省略任何显式定义时,可能会出现未定义行为的行为。”如果整数类型的值表示不是每个都明确声明为未指定/实现定义,那么依赖于值表示的代码将不仅仅是未指定/实现定义,而是 undefined遗漏。
然而,人们也可以争辩说“行为的明确定义”条款不适用,因为行为是完全明确定义的,对象表示是 unsigned char 类型的对象序列,只有它们的值是留给实现。
【问题讨论】:
-
值得注意的是,它避免指定“值表示”或“对象表示”,因此不清楚此处是否打算使用其中任何一种。此处不打算使用这些。它是用于按位运算符的值的 base-2 分解。
-
鉴于此,我能想到四种可能的解释 另一种解释:标准并不意味着实现定义对象/值表示 == 指定如何位在这些表示中与值相关(即使对于可简单复制的类型也不是一对一映射),并且仅意味着指定表示中的位数。如果是这样,则整数的表示由标准指定。
-
那么在这种解释下,位到值的实际映射只是未指定?
-
C++FAQ 没有解决这个问题吗? (C++11 左右基本不说 2 的比较吗?)抱歉,现在查不到。
-
从抽象机的角度来看,是的,从 C++20 开始。但它没有指定实现中的实际值表示,只是表示对于有符号和无符号类型的表示是相同的。
标签: c++ language-lawyer