Title
Address of past-the-end of a potentially-overlapping subobject
Status
open
Section
6.8.4 [basic.compound]
Submitter
Jiang An

Created on 2022-02-20.00:00:00 last changed 2 months ago

Messages

Date: 2024-10-02.22:05:24

CWG 2022-11-11

Unify the treatment of all subobjects by saying the pointer past-the-end has address address(begin) + sizeof(T).

Date: 2022-03-10.21:53:34

Suggested resolution (amended 2022-03-10):

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

A value V 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 object A as follows:

  • If V is a pointer to an object, A is the address of the object as specified in 6.7.2 [intro.object] [ Footnote: ... ] or the first byte in memory after the end of the storage occupied by the object, respectively.
  • If V is a pointer past the end of an object that is not a potentially-overlapping subobject, A is the address of the first byte in memory after the end of the storage occupied by the object.
  • If V is a pointer past the end of a potentially-overlapping subobject, A is an implementation-defined choice of an address within the complete object or the address of the first byte in memory after the end of the storage occupied by the complete object.
  • If V is a null pointer value or an invalid pointer value, V does not represent an address.

Date: 2022-02-20.00:00:00

6.8.4 [basic.compound] paragraph 3 states:

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 object [ Footnote: ... ] or the first byte in memory after the end of the storage occupied by the object, respectively.

A potentially-overlapping subobject of type T may occupy fewer bytes than indicated by sizeof(T), yet pointer arithmetic will only consider sizeof(T), not the number of actually occupied bytes. For example,

struct X {
  X() = default;
  int x;
  short y;
};

struct S {
  [[no_unique_address]] X x;
  short z;
};

static_assert(sizeof(X) == sizeof(S));

On a popular implementation, z is actually put into the tail padding of x, and thus &S().x + 1 does not actually point to "the first byte in memory after the end of the storage occupied by" x.

History
Date User Action Args
2024-10-01 10:32:18adminsetmessages: + msg7830
2022-02-20 00:00:00admincreate
2022-02-18 07:47:23adminsetmessages: + msg6754