对从分配器返回的指针进行指针算术是否格式良好?

问题描述 投票:0回答:1

我知道这个问题过去已经被问过并得到了一些回答。
然而,我对尚未弄清楚的细节存有疑问(或者至少我找不到 QA)。

考虑以下代码:

T *mem = allocator_traits::allocate(allocator, 10);
allocator_traits::construct(allocator, mem+1, params...);

我正在

mem[1]
处构造一个对象,即使
mem[0]
处的对象尚不存在。 据我了解,指针算术是在创建的非构造对象数组上定义良好的。然而,this QA 并没有回答这个具体案例:

我应该指出,当我说 storage + i 将在 P0593 下明确定义时,我假设元素 storage[0]、storage[1]、...、storage[i-1] 已经被构造。尽管我不确定我对 P0593 的理解是否足够好,无法得出结论,它不会涵盖那些尚未构建的元素的情况。

换句话说,作者说这可能是UB。另一方面,这将使

std::vector
实现不可能执行如下操作:

buf_end_size = newbuf + sizeof(T) * size();

因为我希望它是有效的代码(并且我在某些实现中看到了这一点),所以这意味着在未构造对象时,对于

i
的任何值都可以很好地定义指针算术。

所以,我的问题是:这是 UB 还是我可以在任何情况下安全地对

allocate
返回的指针进行指针算术,例如,如果我想在位置 0 之前构造位置 1 的元素?另外,C++17 和 C++20 之间的答案有变化吗?

c++ c++17 language-lawyer c++20 pointer-arithmetic
1个回答
0
投票

我认为这是标准中关于指针算术的相关文本。基本上,如果您在两个指针之间进行加法/减法并且结果没有超出保留数组的范围,则行为是明确定义的。我相信你想要做的事情是明确定义的,因为你已经保留了一个内存数组。

https://eel.is/c++draft/expr.add#5

© www.soinside.com 2019 - 2024. All rights reserved.