struct X { const int n; }; union U { X x; float f; }; void tong() { U u = {{ 1 }}; u.f = 5.f; // OK, creates new subobject of u ([class.union]) X *p = new (&u.x) X {2}; // OK, creates new subobject of u assert(p->n == 2); // OK assert(*std::launder(&u.x.n) == 2); // OK assert(u.x.n == 2); // undefined behavior, u.x does not name new subobject }
template<typename ...T> struct AlignedUnion { alignas(T...) unsigned char data[max(sizeof(T)...)]; }; int f() { AlignedUnion<int, char> au; int *p = new (au.data) int; // OK, au.data provides storage char *c = new (au.data) char(); // OK, ends lifetime of *p char *d = new (au.data + 1) char(); return *c + *d; // OK } struct A { unsigned char a[32]; }; struct B { unsigned char b[16]; }; A a; B *b = new (a.a + 8) B; // a.a provides storage for *b int *p = new (b->b + 4) int; // b->b provides storage for *p // a.a does not provide storage for *p (directly), // but *p is nested within a (see below)
static const char test1 = 'x';
static const char test2 = 'x';
const bool b = &test1 != &test2; // always true