【发布时间】:2018-06-12 12:44:14
【问题描述】:
根据answer,从 C++17 开始,即使指针具有正确的地址和正确的类型取消引用它也可能导致未定义的行为。
alignas(int) unsigned char buffer[2*sizeof(int)];
auto p1=new(buffer) int{};
auto p2=new(p1+1) int{};
*(p1+1)=10; // UB since c++17
原因是p1+1的指针值是a pointer past-the-end of一个对象。可以使用std::launder 将这个示例恢复到定义的行为:
*std::launder(p1+1)=10; // still UB?
其次,在下面这种情况下也有用吗?
alignas(int) unsigned char buffer[3*sizeof(int)];
auto pi = new (buffer) int{};
auto pc = reinterpret_cast<unsigned char*>(pi);//not a "pointer to" an element of buffer
//since buffer[0] and *pc
//are not pointer interconvertible
//pc+2*sizeof(int) would be UB
auto pc_valid = std::launder(pc) //pc_valid is a pointer to an element of buffer
auto pc_valid2 = pc_valid+2*sizeof(int); //not UB thanks to std::launder
auto pi2 = new (pc_valid2) int{};
【问题讨论】: