对于非数组对象类型,尾数指针可以吗?

Is one-past-end pointer OK for non-array object types?

这是有效的 C++ 吗?

int main()
{
    int i = 0;
    int* pi = &i;
    ++pi;
}

我知道数组类型允许使用尾数指针,但在这种情况下我不确定。该代码在技术上是否具有未定义的行为?

是的,没关系。它是任何指针类型都可以持有的四类值之一。

[basic.compound] (emphasis mine)

3 Every value of pointer type is one of the following:

  • a pointer to an object or function (the pointer is said to point to the object or function), or
  • a pointer past the end of an object ([expr.add]), or
  • the null pointer value ([conv.ptr]) for that type, or
  • an invalid pointer value.

A value of a pointer type that is a pointer to or past the end of an object represents the address of the first byte in memory ([intro.memory]) occupied by the object or the first byte in memory after the end of the storage occupied by the object, respectively. [ Note: A pointer past the end of an object ([expr.add]) is not considered to point to an unrelated object of the object's type that might be located at that address. A pointer value becomes invalid when the storage it denotes reaches the end of its storage duration; see [basic.stc]. — end note ] 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.

如你所见,这里也提到了数组类型,其假设的对象在末尾。正如 footnote in [expr.add] 所解释的那样,获得尾后一个指针的算法 意味着 也有效:

As specified in [basic.compound], an object that is not an array element is considered to belong to a single-element array for this purpose and a pointer past the last element of an array of n elements is considered to be equivalent to a pointer to a hypothetical array element n for this purpose.