c++ pointers c++17

Uso de std:: launder para "validar" el valor del puntero que no sea "puntero a objeto" desde C++ 17



pointers c++17 (1)

De acuerdo con esta answer , desde C ++ 17, incluso si un puntero tiene la dirección correcta y el tipo correcto de desreferenciado puede causar un comportamiento indefinido .

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

La razón es que el valor del puntero de p1+1 es un puntero que se encuentra más allá del final de un objeto. ¿Se puede devolver este ejemplo a un comportamiento definido utilizando std::launder :

*std::launder(p1+1)=10; // still UB?

En segundo lugar, ¿también sería útil en este siguiente caso?

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{};


No. Los bytes que constituyen el objeto int p2 puntos no son reachable través de p1+1 .

La regla de "alcance" básicamente significa que el launder no le permite acceder al almacenamiento al que no puede acceder legalmente a través del puntero original. Dado que una función opaca puede launder punteros tanto como quiera, permitir este tipo de chanchullos inhibiría sustancialmente el análisis de escape.