Why doesn't std::launder
return the correct value (2) in CLANG and GCC when the object is in the stack v in the heap? Even using std::launder
.
std::launder
is required. See this which says launder
is needed when replacing an object const qualified at the top level. This is because
basic.life 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.
CodePudding user response:
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.