c++ - 标准中关于超出范围指针的未定义行为的歧义

标签 c++ c++11 language-lawyer semantics undefined-behavior

ISO IEC 14882-2011 §5.7/5 状态:

If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

本节有时会在 stackoverflow 上使用。例如,争论为什么指向 nullptr 的指针的增量是 UB,如 here .然后它被解释为,有一个不指向数组对象元素的指针。是未定义的行为。

然而,当我读到这篇文章时,我理解它是指指针的评估是 UB。这意味着拥有这样一个指针是明确定义的行为。当一个人试图取消引用它时,行为变得不确定。

这意味着,例如,将有效指针递增到数组边界之外是合法的。之后再次递减它是合法的。并且由于指针将与增量之前的值相同,因此评估也是合法的。

这两个是哪个?

最佳答案

您引用的段落指的是指针算术,而不是指针求值。

它声明唯一的时间指针加法 p + i 被定义为 if
(将 i 的减法等同于 -i 的加法)

  1. p 指向数组对象的一个​​元素或最后一个元素之后的一个元素,并且
  2. 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

关于c++ - 标准中关于超出范围指针的未定义行为的歧义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30369357/

相关文章:

c++ - 来自 std::promise 的未知异常

c++ - 为什么从 char 转换为 std::byte 可能是未定义的行为?

c++ - 解引用指针的地址

c++ - C++中的点和线类?

c++ - 在 dynamic_pointer_cast 之后调用派生类的构造函数

c++ - 从模板类中获取 "sub-type"

c++ - 浮点运算是否会导致 IEC 559/IEEE 754 浮点类型的无限未定义行为

rust - Rust 的词汇语法是正则的、上下文无关的还是上下文敏感的?

c++ - 如何在虚方法上使用模板参数类?

c++ - 如何使用 std::transform 进行计算