ISO IEC14882-2011§5.7/ 5 国家:
如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出;否则,行为未定义。
此部分在此处不时用于stackoverflow。例如,争论为什么指向nullptr
的指针的增量为UB,如here。然后将其解释为具有不指向数组对象的元素的指针。是未定义的行为。
然而,当我读到这篇文章时,我理解它指的是指针是UB的评估。这意味着拥有这样的指针是明确定义的行为。当一个人试图取消引用它时,行为就变得不确定了。
这意味着,例如,将有效指针递增到数组边界之外是合法的。之后再次减少是合法的。并且由于指针将与增量之前的值相同,因此评估也是合法的。
两者中哪一个是这样的?
答案 0 :(得分:4)
您引用的段落是指针运算,而不是指针的评估。
它声明指定添加p + i
的唯一时间是否为
(将i
减法等同于-i
)
p
指向数组对象的元素或指向最后一个元素的元素,p + i
指向同一个数组对象的元素,或者指向最后一个元素的元素如果p
不是指向数组元素的指针或“一个超过结尾” - 例如,如果它是空指针或“两个结束” - 行为未定义。
您不需要取消引用结果以导致未定义的行为 - 添加本身的效果未定义。
也就是说
int p[1] = {0};
int *q = p; // OK
q = q + 1; // OK - one past the end
int *r = q + 1; // Undefined behaviour
r = r - 1; // Doesn't make r valid or the program un-undefined
同样
int *p = nullptr;
p++; // Undefined
p--; // Still undefined
答案 1 :(得分:3)
&#34;评估&#34;是指添加剂操作的评估;因此,在非评估的上下文(static_cast<int*>(nullptr) + 1
,sizeof
等)中(例如)decltype
不会出现UB。
它并不意味着&#34;指针的评估&#34;,当然不会解除引用它;如果标准有意这样的解释,它就会这么说。
答案 2 :(得分:0)
递增然后递减空指针仍然是未定义的行为。当UB发生时,任何事情都可能发生,因此这将是一个有效的事件序列:
0xDEADBEEF
,因为我们可以。0xDEADBEEF
碰巧位于第一个元素之后的有效数组中,否则还会出现未定义的行为。