Description
Full name of submitter (unless configured in github; will be published with the issue): Jim X
[expr.add] p4.2 says:
When an expression J that has integral type is added to or subtracted from an expression P of pointer type, the result has the type of P.
- [...]
- Otherwise, if P points to an array element i of an array object x with n elements ([dcl.array]), the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) array element i+j of x if 0≤i+j≤n and the expression P - J points to the (possibly-hypothetical) array element i−j of x if 0≤i−j≤n.
According to the definition of the array element in [dcl.array] p6
An object of type “array of N U” consists of a contiguously allocated non-empty set of N subobjects of type U, known as the elements of the array, and numbered 0 to N-1.
That is, the hypothetical element is not, in terms of this definition, an element of the array. Consider this example:
int main(){
int a = 0;
int *p = (&a + 1); // p points to the hypothetical element of an array of type `int[1]`
int *back = p -1; // #1
}
When applying [expr.add] p4.2 to #1
, as above stated, p
does not point to an element as per the definition in [dcl.array] p6, so this example eventually falls into [expr.add] p4.3, and is UB?
However, the note of [expr.add] p4.2 seems to admit the rule can apply to the case when P
points to a hypothetical element
- 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.
Suggested Resolution
Otherwise, if P points to an array element i (including the hypothetical element) of an array object x with n elements ([dcl.array])