哪些指针值被明确定义为可以计算?
What pointer values are well-defined to compute?
我的印象是,虽然取消引用未指向有效对象的指针是 UB,但只需计算此类指针就可以了。
但是,如果我的理解是正确的 expr.add[4],那么事实并非如此。
那么这些指针计算中哪些是明确定义的?
int a = 42;
int *p = &a;
p; // valid, and obviously ok
p++; // invalid, but ok, because one past the end of 'array' containing 1 element?
p++; // UB ?
这个案例怎么样?
int *p = nullptr;
p; // invalid, and obviously ok (considered one past the end?)
p++; // one past the end? or UB?
在您的第一个示例中,第一个 p++
是明确定义的,因为非数组被视为单长度数组。
这是相关的引用 (basic.compound/3.4):
For purposes of pointer arithmetic ([expr.add]) and comparison ([expr.rel], [expr.eq]), a pointer past the end of the last element of an array x of n elements is considered to be equivalent to a pointer to a hypothetical array element n of x and an object of type T that is not an array element is considered to belong to an array with one element of type T.
在 p++
、p
之后,它将指向明确定义的(假设的)数组的最后一个(也是唯一的)元素。它不是“无效,但可以”,因为指向对象末尾的指针不是无效指针,basic.compound/3.2:
Every value of pointer type is one of the following:
[...]
a pointer past the end of an object
[...]
an invalid pointer value.
第一个例子的第二个p++
是UB,因为结果会指向假设的(&a)[1]元素之后,这个元素没有定义。
在你的第二个例子中,p++
是 UB,因为只能将 0 添加到 nullptr
(expr.add/4.1):
If P evaluates to a null pointer value and J evaluates to 0, the result is a null pointer value.
[...]
Otherwise, the behavior is undefined.
我的印象是,虽然取消引用未指向有效对象的指针是 UB,但只需计算此类指针就可以了。
但是,如果我的理解是正确的 expr.add[4],那么事实并非如此。
那么这些指针计算中哪些是明确定义的?
int a = 42;
int *p = &a;
p; // valid, and obviously ok
p++; // invalid, but ok, because one past the end of 'array' containing 1 element?
p++; // UB ?
这个案例怎么样?
int *p = nullptr;
p; // invalid, and obviously ok (considered one past the end?)
p++; // one past the end? or UB?
在您的第一个示例中,第一个 p++
是明确定义的,因为非数组被视为单长度数组。
这是相关的引用 (basic.compound/3.4):
For purposes of pointer arithmetic ([expr.add]) and comparison ([expr.rel], [expr.eq]), a pointer past the end of the last element of an array x of n elements is considered to be equivalent to a pointer to a hypothetical array element n of x and an object of type T that is not an array element is considered to belong to an array with one element of type T.
在 p++
、p
之后,它将指向明确定义的(假设的)数组的最后一个(也是唯一的)元素。它不是“无效,但可以”,因为指向对象末尾的指针不是无效指针,basic.compound/3.2:
Every value of pointer type is one of the following:
[...]
a pointer past the end of an object
[...]
an invalid pointer value.
第一个例子的第二个p++
是UB,因为结果会指向假设的(&a)[1]元素之后,这个元素没有定义。
在你的第二个例子中,p++
是 UB,因为只能将 0 添加到 nullptr
(expr.add/4.1):
If P evaluates to a null pointer value and J evaluates to 0, the result is a null pointer value.
[...]
Otherwise, the behavior is undefined.