Why doesn't std::launder return the correct value (2) in Clang and GCC when the object is on the stack, and not on the heap? Even using std::launder.
std::launder is required. See [ptr.launder]/5 which says std::launder
is needed when replacing an object const qualified at the top level. This is because
[basic.life]/8 disallows replacing complete const objects without std::launder, only
sub-objects.
#include <memory>
#include <iostream>
int main()
{
struct X { int n; };
const X *p = new const X{1};
const X x{1};
std::construct_at(&x, X{2}); // on stack
const int c = std::launder(&x)->n;
std::construct_at(p, X{2}); // allocated with new
const int bc = std::launder(p)->n;
std::cout << c << " " << '\n';
std::cout << bc << " " << '\n';
}
See Compiler Explorer.
std::construct_at(&x, X{2}); has undefined behavior.
It is not allowed to create a new object in storage that was previously occupied by a const complete object with automatic, static or thread storage duration. (see [basic.life]/10)
Other than that you are correct that std::launder is required in the second case for the reasons you explained: Because the object you created with new is const-qualified. If it weren't for that the old object would be transparently replaceable with the new one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With