为何对多维数组使用std::launder会导致未定义行为?
关于std::launder代码片段的未定义行为解释
先明确代码里的关键类型:
&x2[0][0]是指向x2[0]第一个元素的int*指针;reinterpret_cast<int(*)[10]>(&x2[0][0])将其转换为指向10个int的数组的指针,该指针逻辑上指向x2[0](因为x2[0]的起始地址与x2[0][0]完全重合);- 最终通过
std::launder处理转换后的指针得到p2。
这段代码触发未定义行为的核心原因是std::launder的可达性规则:
调用 std::launder 后返回的指针,仅允许访问原指针(转换前的int*)可达的对象。
这里的「可达对象」定义为:
- 原指针直接指向的对象(
x2[0][0]); - 与该对象同属一个数组/联合体的其他对象(
x2[0]的所有元素,以及x2[0]本身); - 上述对象的子对象。
而 x2[1] 是独立于 x2[0] 的另一个数组对象,不属于原指针的可达范围。
但转换后的 p2 是指向10个int数组的指针,通过指针算术(比如 p2 + 1)可以得到指向 x2[1] 的指针,进而访问 x2[1] 的元素——这直接超出了原指针的可达范围。即便你没有实际执行 p2+1 这类操作,标准依然判定这段代码为未定义行为,因为 std::launder 的返回指针不允许扩展原指针的访问边界。
本质上:std::launder 不能用来「解锁」原指针本来无法访问的对象,哪怕这些对象在内存上是相邻的。
内容的提问来源于stack exchange,提问作者user10260481
相关产品推荐
相关产品推荐

