Hello,
I recently noticed something unexpected: it is possible to construct an object over constant storage with `std::construct_at`. At least it works in gcc 13.2.0 and clang 18.
Note that this is not possible with placement new.
I tried playing with the following code:
template <class
T>
void swap_const_references(T
const&
a, T
const& b)
{
T c{a};
a.~T();
std::construct_at(&a,
b);
b.~T();
std::construct_at(&b,
c);
}
And it compiles fine with both compilers. If I replace the std::construct_at with placement new, the code fails to compile (cannot convert 'const void*' to 'void*').
This swap_const_references is definitely something we don't want to be able to write! At least not without relying on UB. I can even make it constexpr and it is still compiling >< (and working as designed...)
I don't know who is in the wrong here, between the library implementers and the C++ standard. But here is a case where code with a non-constexpr placement new is actually safer than the shinny construct_at...
Should we open a defect to fix std::construct_at so it does not accept constructing over constant storage?
Best regards,
S¨¦bastien BINI