假设我想在不调用任何未定义行为(UB)的情况下实现std :: vector。下面的代码是否调用UB:
struct X{int i;};
int main(){
auto p = static_cast<X*>(::operator new(sizeof(X)*2));
new(p) X{};
new(p+1) X{};// p+1 UB?
}
从标准中选择引用内容可能会有所帮助:
[basic.stc.dynamic.allocation]
(由分配函数返回的指针应适当对齐,以便可以将其转换为指向任何指针的指针合适的完整对象类型(21.6.2.1),然后用于访问分配的存储中的对象或数组(直到通过调用相应的释放函数显式释放存储)。
[expr.add]
当将具有整数类型的表达式添加到指针或从指针中减去时,结果具有该类型指针操作数的值。如果表达式P指向具有n个元素的数组对象x的元素x [i],表达式P + J和J + P(其中J的值为j)指向(possible-hypothetical)元素x [i + j]如果0 <= i + j <= n;否则,行为是不确定的。同样,表达式P-J指向(可能假设)元素x [i-j]如果0 <= i-j <= n;否则,行为是不确定的。
我的解释是,分配提供了一个可能假想的X数组(在C ++数组中是对象),因此,例如在分配的存储上的指针算法可能不会调用未定义的行为。还是我对hypothetical的解释是错误的?如果先前的代码片段是UB,该怎么办?