使用std :: launder来“验证"非“指向对象的指针";自C ++ 17以来的指针值 [英] Using std::launder to "validate" non "pointer to object" pointer value since C++17
问题描述
根据此 answer ,自C ++ 17起,即使指针具有正确的地址和正确的类型取消引用可能会导致不确定的行为.
According to this answer, since C++17, even if a pointer has the right address and the right type dereferencing it can cause undefined behaviour.
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
的指针值为 对象后的指针 .是否可以使用std::launder
将这个示例恢复为已定义的行为:
The reason is that the pointer value of p1+1
is a pointer past-the-end of an object. Can this example be brought back to defined behavior using std::launder
:
*std::launder(p1+1)=10; // still UB?
第二,在以下情况下,它是否也有用?
Secondly, would it also be useful in this following case?
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{};
推荐答案
否.构成int
对象p2
指向的字节不是可以通过p1+1
到达.
No. The bytes constituting the int
object p2
points to are not reachable through p1+1
.
可达"规则基本上意味着launder
不允许您访问无法通过原始指针合法访问的存储.由于不透明函数可能会根据需要尽可能地launder
指针,因此允许这种假名将实质上抑制转义分析.
The "reachable" rule basically means that launder
doesn't allow you to access storage you can't legally access via the original pointer. Since an opaque function may launder
pointers as much as it wants, permitting this kind of shenanigans would substantially inhibit escape analysis.
这篇关于使用std :: launder来“验证"非“指向对象的指针";自C ++ 17以来的指针值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!