C++ 使用std::流槽“清洗”;“验证”;非「;指向对象的指针;自C++;17

C++ 使用std::流槽“清洗”;“验证”;非「;指向对象的指针;自C++;17,c++,pointers,c++17,C++,Pointers,C++17,根据这一点,自C++17以来,即使指针具有正确的地址和正确的类型,它也可能导致未定义的行为 原因是p1+1的指针值是一个对象。是否可以使用std::launder将此示例带回定义的行为: *std::launder(p1+1)=10; // still UB? 第二,在以下情况下,它是否也有用 alignas(int) unsigned char buffer[3*sizeof(int)]; auto pi = new (buffer) int{}; auto pc = reinterp

根据这一点,自C++17以来,即使指针具有正确的地址和正确的类型,它也可能导致未定义的行为

原因是
p1+1
的指针值是一个对象。是否可以使用
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{};
alignas(int)无符号字符缓冲区[3*sizeof(int)];
自动pi=新(缓冲区)int{};
自动pc=重新解释铸件(pi)//不是缓冲区元素的“指针”
//自缓冲区[0]和*pc
//指针不可相互转换
//pc+2*sizeof(int)将为UB
auto pc\u valid=std::launder(pc)//pc\u valid是指向缓冲区元素的指针
自动pc_valid2=pc_valid+2*sizeof(int)//由于std::launder,没有UB
自动pi2=新(pc_valid2)int{};

否。构成
int
对象
p2
指向的字节不是通过
p1+1



“可访问”规则基本上意味着
launder
不允许您访问无法通过原始指针合法访问的存储。由于不透明函数可以
任意清洗
指针,因此允许这种恶作剧将极大地抑制逃逸分析。

对于第二个例子,它有意义吗?答案相同。数组的剩余
2*sizeof(int)
字节无法通过
pi
访问,直到cxdraft htmlgen也创建到单个句子的链接。Neat@T.C.:我当然知道有必要区分那些永远不会用来派生外部对象的指针和那些可能会派生外部对象的指针,但是一种没有任何指针类型可以保留派生外部对象地址的语言从根本上来说比没有指针类型的语言要弱。@t.C.:进一步,通常需要的不是清洗指针并使其无限期可用的能力,而是创建指向对象的指针的能力,该对象可以访问其他对象,但在其生命周期内,将受到类似于C的
restrict
的限制。从本质上讲,创建和销毁这样一个指针会成为排序障碍,但使用它们不会。在紧密循环中创建此类指针的代码可能会执行得很糟糕,但能够在循环外设置障碍可能会使代码比其他方式更高效。
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{};