This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115c. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-09-25


2419. Loss of generality treating pointers to objects as one-element arrays

Section: 7.6.6  [expr.add]     Status: C++20     Submitter: Andrey Erokhin     Date: 2019-07-15

[Adopted as a DR at the November, 2019 meeting.]

CCCC,

Before the resolution of issue 1596, 7.6.6 [expr.add] specified that:

For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

where “these operators” refers to the additive operators. This provision thus applied to any pointer, regardless of its provenance. In its place, the normative provision for this treatment was restricted to the & operator only, in 7.6.2.2 [expr.unary.op] paragraph 3:

For purposes of pointer arithmetic (7.6.6 [expr.add]) and comparison (7.6.9 [expr.rel], 7.6.10 [expr.eq]), an object that is not an array element whose address is taken in this way is considered to belong to an array with one element of type T.

Thus, for example:

  int *p1 = new int;
  int *p2 = &*p1;
  bool b1 = p1 < p1+1;  // undefined behavior
  bool b2 = p2 < p2+1;  // well-defined

This restriction does not seem desirable.

Proposed resolution (October, 2019):

  1. Change 7.6.2.2 [expr.unary.op] bullet 3.2 as follows:

  2. The result of the unary & operator is a pointer to its operand.

  3. Change 6.8.4 [basic.compound] paragraph 3 as follows:

  4. ...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 (6.7.1 [intro.memory]) occupied by the object43 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 (7.6.6 [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 6.7.5 [basic.stc]. —end note] For purposes of pointer arithmetic (7.6.6 [expr.add]) and comparison (7.6.9 [expr.rel], 7.6.10 [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 element x[n] 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. The value representation of pointer types...
  5. Change the footnote in 7.6.6 [expr.add] bullet 4.2 as follows:

  6. 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.

  7. Change the footnote in 7.6.9 [expr.rel] paragraph 4 aa follows:

  8. The result of comparing unequal pointers to objects [Footnote: An As specified in 6.8.4 [basic.compound], an object that is not an array element is considered to belong to a single-element array for this purpose; see 7.6.2.2 [expr.unary.op]. A and a pointer past the last element of an array x of n elements is considered to be equivalent to a pointer to a hypothetical array element x [ n ] n for this purpose; see 6.8.4 [basic.compound]. —end footnote] is defined in terms of a partial order consistent with the following rules:
  9. Change 27.10.16 [numeric.ops.midpoint] paragraph 5 as follows:

  10. Expects: a and b point to, respectively, elements x[i] and x[j] of the same array object x. [Note: An As specified in 6.8.4 [basic.compound], an object that is not an array element is considered to belong to a single-element array for this purpose; see 7.6.2.2 [expr.unary.op]. A and a pointer past the last element of an array x of n elements is considered to be equivalent to a pointer to a hypothetical array element x[n] n for this purpose; see 6.8.4 [basic.compound]. —end note]