Title
Loss of generality treating pointers to objects as one-element arrays
Status
c++20
Section
7.6.6 [expr.add]
Submitter
Andrey Erokhin

Created on 2019-07-15.00:00:00 last changed 40 months ago

Messages

Date: 2019-10-15.00:00:00

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.

    • ...

    • Otherwise, if the operand is an lvalue of type T, the resulting expression is a prvalue of type “pointer to T” whose result is a pointer to the designated object (6.7.1 [intro.memory]) or function. [Note: In particular, taking the address of a variable of type “cv T” yields a pointer of type “pointer to cv T”. —end note] 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.

    • ...

  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.

    • ...

    • Otherwise, if P points to an array element i of an array object x with n elements (9.3.4.5 [dcl.array]), [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 n for this purpose; see 6.8.4 [basic.compound]. —end footnote] the expressions...

  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]
Date: 2019-11-15.00:00:00

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

History
Date User Action Args
2020-12-15 00:00:00adminsetmessages: + msg6442
2019-07-15 00:00:00admincreate