Created on 2023-06-08.00:00:00 last changed 3 hours ago
Additional notes (CWG 2026-01-23):
Consider:
A x{}: // implicit object creation for x.buf
A* p = reinterpret_cast<A*>(x.buf); // nailed down A at x.buf
There is no pointer interconvertibility between x.buf and x, so there must be a second A at x.buf.
Also consider:
struct S {
unsigned char c[1];
};
unsigned char a[sizeof(S)];
S* ps = new (a) S; // must create S inside a buffer; now have two "array of unsigned char" at the same address
Also consider:
struct B {};
struct A : B {};
struct C : B {};
struct D : A, C { unsigned char x[2]; };
D d;
new (d.x+1) C();
The A and C base classes must have different offsets (because their B bases must have different offsets), thus #2 creates a C object at the offset of the existing C base class object.
Suggested resolution:
Change in 6.8.2 [intro.object] paragraph 3 as follows:
If a complete object of type T is created (7.6.2.8 [expr.new]) in storage associated with another object e of type “array of N unsigned char” or of type “array of N std::byte” (17.2.1 [cstddef.syn]), that array provides storage for the created object if:
- the lifetime of e has begun and not ended, and
- the storage for the new object fits entirely within e, and
- e is not and is not nested within an object of type similar (7.3.6 [conv.qual]) to T that is within its lifetime, and
- there is no array object that satisfies these constraints nested within e.
(From thread beginning here.)
Consider:
#include <new>
struct A { unsigned char buf[1]; };
static_assert(sizeof(A) == 1); // A can fit within A::buf
int main()
{
A x{};
new (x.buf) A{};
}
A::buf provides storage for another A object. Thus, there are now two objects of type A within lifetime, which is inconsistent with the goal expressed by 6.8.2 [intro.object] paragraph 9.
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2026-01-23 19:03:24 | admin | set | messages: + msg8461 |
| 2023-06-09 07:14:31 | admin | set | messages: + msg7308 |
| 2023-06-08 00:00:00 | admin | create | |