使用std :: wash来"验证" non"指向对象的指针"自C ++ 17以来的指针值

时间:2018-01-02 20:14:35

标签: c++ pointers c++17

根据这个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{};

1 个答案:

答案 0 :(得分:12)

没有。构成int对象p2的字节指向的不是reachablep1+1

&#34;可达&#34;规则基本上意味着launder不允许您访问您无法通过原始指针合法访问的存储空间。由于不透明函数可能launder指向它想要的多少,允许这种恶作剧会大大抑制逃逸分析。