c++ `std::launder`对于Clang和GCC不返回正确的数据,但是对于MSVC

mpbci0fu  于 2023-06-07  发布在  其他
关注(0)|答案(1)|浏览(141)

为什么在Clang和GCC中,当对象在堆栈上而不是堆上时,std::launder不返回正确的值(2)?即使使用std::launder。需要std::launder。请参阅[ptr.launder]/5,其中说明在替换顶级限定的对象常量时需要std::launder。这是因为[basic.life]/8不允许替换没有std::launder的完整const对象,只允许替换子对象。

#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';
}

参见Compiler Explorer

7vux5j2d

7vux5j2d1#

std::construct_at(&x, X{2});有未定义的行为。
不允许在先前由const完整对象占用的存储中创建新对象,该对象具有自动、静态或线程存储持续时间。(见[basic.life]/10)
除此之外,你是正确的,因为你解释的原因,在第二种情况下需要std::launder:因为用new创建的对象是const限定的。如果不是这样的话,旧的对象将被新的对象“透明地替换”。

相关问题