【发布时间】:2018-06-18 18:40:42
【问题描述】:
C++17 标准似乎说,如果指针指向数组元素,则只能将整数添加到指针,或者,作为特殊例外,指针是一元运算符 & 的结果:
8.5.6 [expr.add] 描述对指针的加法:
当一个整数类型的表达式被添加到指针或从指针中减去时,结果具有指针操作数的类型。如果表达式 P 指向具有 n 个元素的数组对象的元素 x[i] x,则表达式 P + J 和 J + P(其中 J 的值为 j)指向(可能-假设的)元素 x[i + j] 如果 0 ≤ i + j ≤ n; 否则,行为未定义。
此引用包含non-normative 脚注:
为了这个目的,一个不是数组元素的对象被认为属于一个单元素数组; 见 8.5.2.1
引用 8.5.2.1 [expr.unary.op] 讨论一元 & 运算符:
一元 & 运算符的结果 是一个指向其操作数的指针...对于指针算术 (8.5.6) 和比较 (8.5.9, 8.5.10),一个对象不是数组元素其地址是以这种方式获取的被认为属于具有一个 T 类型元素的数组。
非规范脚注似乎有点误导,因为它引用的部分描述了特定于一元运算符 & 的结果的行为。似乎没有任何东西允许将其他指针(例如来自非数组 new)视为单元素数组。
这似乎表明:
void f(int a) {
int* z = (new int) + 1; // undefined behavior
int* w = &a + 1; // ok
}
这是对 C++17 所做更改的疏忽吗?我错过了什么吗?是否有理由只为一元运算符&提供“单元素数组规则”?
注意:如标题中所述,此问题特定于 C++17。 C 标准和 C++ 标准的早期版本包含不再存在的清晰规范语言。像 this 这样较老的模糊问题不相关。
【问题讨论】:
-
"非规范脚注似乎有点误导" 这就是非规范符号的用途。他们用简单的英语解释了一些在别处更明确地详细说明的东西。 “是否有理由只为一元运算符 & 提供“单元素数组规则”?” 是否有理由为其他东西提供它?
-
@NicolBolas 如果您使用
new分配单个对象,您仍然有一个指向单个对象的指针而不使用&,正如OP 所述。问题是这条规则是否也适用于这种情况(或相关情况)。 -
对我来说似乎是一个疏忽,因为
p==&*p的定义。 -
嗯,我个人将 8.5.2.1 解释为:如果我们这样取地址,那么我们有......没有提到对于 else 明确表示,所以状态还 open。 8.5.6 概括了脚注中的问题,将单元素数组规则扩展到 else 情况。规范扩展——见@n.m。的评论...
标签: c++ arrays pointers language-lawyer c++17