Created on 2023-06-29.00:00:00 last changed 8 months ago
CWG 2023-07-14
CWG resolved that a named or temporary object is always disjoint from any other object, and thus cannot overlap with a string literal object or a backing array. The lines b4 and b5 in the example highlight that outcome.
Backing arrays and string literals can arbitrarily overlap among themselves; CWG believes the proposed wording achieves that outcome.
The ancillary question how address comparisons between potentially non-unique objects are treated during constant evaluation is handled in issue 2765.
Proposed resolution (approved by CWG 2023-11-09):
Add a new paragraph before 6.7.2 [intro.object] paragraph 9 and change the latter as follows:
An object is a potentially non-unique object if it is a string literal object (5.13.5 [lex.string]), the backing array of an initializer list (9.4.4 [dcl.init.ref]), or a subobject thereof.
Unless an object is a bit-field or a subobject of zero size, the address of that object is the address of the first byte it occupies. Two objects with overlapping lifetimes that are not bit-fields may have the same address if one is nested within the other, or if at least one is a subobject of zero size and they are of different types, or if they are both potentially non-unique objects; otherwise, they have distinct addresses and occupy disjoint bytes of storage.
[Example 2:
static const char test1 = 'x'; static const char test2 = 'x'; const bool b = &test1 != &test2; // always true static const char (&r) [] = "x"; static const char *s = "x"; static std::initializer_list<char> il = { 'x' }; const bool b2 = r != il.begin(); // unspecified result const bool b3 = r != s; // unspecified result const bool b4 = il.begin() != &test1; // always true const bool b5 = r != &test1; // always true-- end example]
Change in subclause 5.13.5 [lex.string] paragraph 9 as follows:
Evaluating a string-literal results in a string literal object with static storage duration (6.7.6 [basic.stc]). [ Note: String literal objects are potentially non-unique (6.7.2 [intro.object]). Whetherall string-literals are distinct (that is, are stored in nonoverlapping objects) and whethersuccessive evaluations of a string-literal yield the same or a different object is unspecified. -- end note ]
Change in subclause 9.4.4 [dcl.init.ref] paragraph 5, after application of P2752R3 (approved in June, 2023), as follows:
Whether all backing arrays are distinct (that is, are stored in non-overlapping objects) is unspecified.[ Note: Backing arrays are potentially non-unique objects (6.7.2 [intro.object]). -- end note ]
[Accepted as a DR at the November, 2023 meeting.]
Subclause 6.7.2 [intro.object] paragraph 9 specifies the general principle that two objects with overlapping lifetimes have non-overlapping storage, which can be observed by comparing addresses:
Unless an object is a bit-field or a subobject of zero size, the address of that object is the address of the first byte it occupies. Two objects with overlapping lifetimes that are not bit-fields may have the same address if one is nested within the other, or if at least one is a subobject of zero size and they are of different types; otherwise, they have distinct addresses and occupy disjoint bytes of storage.
After P2752, there are two exceptions: string literal objects and backing arrays for initializer lists.
Subclause 5.13.5 [lex.string] paragraph 9 specifies:
Evaluating a string-literal results in a string literal object with static storage duration (6.7.6 [basic.stc]). Whether all string-literals are distinct (that is, are stored in nonoverlapping objects) and whether successive evaluations of a string-literal yield the same or a different object is unspecified.
Subclause 9.4.4 [dcl.init.ref] paragraph 5, after application of P2752R3 (approved in June, 2023), specifies:
Whether all backing arrays are distinct (that is, are stored in non-overlapping objects) is unspecified.
It is unclear whether a backing array can overlap with a string literal object.
Furthermore, it is unclear whether any such object can overlap with named objects or temporaries, for example:
const char (&r) [] = "foo"; const char a[] = {'f', 'o', 'o', '\0'}; int main() { assert(&r == &a); // allowed not to fail? }
History | |||
---|---|---|---|
Date | User | Action | Args |
2024-04-05 21:43:46 | admin | set | status: dr -> drwp |
2023-12-19 10:15:28 | admin | set | status: ready -> dr |
2023-11-10 14:27:11 | admin | set | status: tentatively ready -> ready |
2023-07-16 13:00:43 | admin | set | messages: + msg7383 |
2023-07-16 13:00:43 | admin | set | messages: + msg7382 |
2023-07-16 13:00:43 | admin | set | status: open -> tentatively ready |
2023-06-29 00:00:00 | admin | create |