Consider the following.
struct T { int a = 1; };
struct U { char b = 2; };
static_assert(alignof(U) == 1);
// Allocate storage. Cast via P0593 to access implicit array of unsigned char.
auto* s = reinterpret_cast<unsigned char*>(::operator new(sizeof(T) + sizeof(U)));
// Place T and U in that storage.
T* t = new (s) T;
U* u = new (s + sizeof(T)) U;
// Is there a legal way to get a pointer to `u` given only `t` and not `s`?
U* u2 = reinterpret_cast<U*>(reinterpret_cast<unsigned char*>(t) + sizeof(T));
The question: Is there a way, given only t to get u?
I know I can std::launder() s to get t, and presumably I can std::launder() s + sizeof(T) to get u. But, if all I have is t, is there a way?
I know that std::launder() has requirements about "reachability", so I don't think it can be part of the solution since u is not reachable from t.
I know that if I put T and U together in a struct, things are different, but that's not the case I am interested in. (Consider that U might actually be of dynamic size.)
I think my question boils down to: How do I recover s (the underlying complete storage) from t? I know I can get the object representation of the object at t, but I don't think that's the same as s because it's only sizeof(T) long, right?
If I want to allocate once and store these non-array disparate objects, am I forced to store a pointer to u inside t just to recover it later?
As you are saying
std::launderhas a precondition that explicit prohibits this. It seems intended to be impossible.There are a few other constructs in the language that can make more bytes reachable than should be possible by this precondition, see e.g. my questions std::launder vs placement-new reachability condition and Does implicit object creation circumvent reachability conditions of std::launder?.
However, given that these restrictions were explicitly added to
std::launder, I suspect that them not being applied to these other constructs as well is the defect and not the other way around.I do not know whether there is any compiler that actually makes use of this reachability restriction for optimization though.