【发布时间】:2017-09-02 21:34:09
【问题描述】:
假设我想在不调用任何未定义行为 (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)指向 (possibly-hypothetical) 元素 x[i + j] 如果 0possibly-hypothetical) 元素 x[i - j] if 0
我的解释是分配提供了一个可能假设的 X 数组(在 C++ 中数组是对象),因此示例中分配的存储上的指针算术可能不会调用未定义的行为。还是我对假设的解释是错误的?如果之前的代码snipest是UB怎么办?
【问题讨论】:
-
其实编译不了。期望您添加几行来实现它是不是太过分了?
-
没有错,为什么不能把代码贴在这里作为问题的一部分?
-
@NeilButterworth:你为什么要这个?这个问题已经完全可以理解了。
-
@NeilButterworth 说真的,我认为很明显表达式必须出现在某些代码块中,并且“...”表示“某事”。我做到了!
-
我认为这里假设的意思是“最后一个元素”。但我不确定。它不应该是UB。但是我让别人回答这个问题,我远不是语言律师。
标签: c++ memory-management language-lawyer