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

2024-11-11


2544. Address of past-the-end of a potentially-overlapping subobject

Section: 6.8.4  [basic.compound]     Status: open     Submitter: Jiang An     Date: 2022-02-20

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.

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:

CWG 2022-11-11

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