【问题标题】:Is pointer arithmetic on allocated storage UB?分配的存储UB上的指针算术是什么?
【发布时间】: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


【解决方案1】:

是的,从技术上讲,它具有未定义的行为,尽管我们倾向于忽略这一点。 P0593 应该正确修复它。

短语“可能假设”是指过去的“元素”(ref),不允许这种情况。

【讨论】:

    猜你喜欢
    • 2023-04-04
    • 2022-10-15
    • 1970-01-01
    • 1970-01-01
    • 2012-01-10
    • 2015-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多