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
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 objectrepresents the addressof the first byte in memory (6.7.1 [intro.memory]) occupied by the objectA 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.
CWG 2022-11-11
Unify the treatment of all subobjects by saying the pointer past-the-end has address address(begin) + sizeof(T).