【发布时间】:2020-09-19 04:33:35
【问题描述】:
在随后的引用中,我指的是 ISO 标准草案 N4713。
第 6.6.3 节第 1 段说:
...类型 T 的对象 o 的生命周期在以下情况下结束:
...
——对象占用的存储被释放,或者被重用 通过不嵌套在 o (6.6.2) 中的对象。
请回答代码cmets中的问题:
#include <new>
int main() {
int x[2] = {0, 1};
char* p = new (x + 1) char{0}; // Has x ended its' lifetime?
int z = x[0]; // Is this UB?
}
如果我使用 unsigned char 作为数组元素类型,则数组对象 x 将为 *p 提供存储,根据 § 6.6.2 第 3 段:
如果在与 另一个类型为“N unsigned char 数组”或“数组”类型的对象 e N std::byte” (21.2.1),该数组为创建的 对象如果:
— e 的生命周期已经开始但没有结束,并且
- 这 新对象的存储完全适合 e,并且
— 没有 满足这些约束的更小的数组对象。
请验证我在代码 cmets 中的陈述:
#include <new>
int main() {
unsigned char x[2] = {0, 1};
char* p = new (x + 1) char{0}; // Only x[1] have ended its' lifetime.
int z = x[0]; // This is OK.
}
虽然我不明白前面引用的最后一条规则,但请举个例子?
没有更小的数组对象可以满足这些约束。
【问题讨论】:
-
§ 6.6.2,第 3 段指的是
unsigned char的数组或std::byte的数组。您的示例两者都没有(如果您的数组为int),因此该部分不适用。 -
您的设置似乎存在更根本的缺陷。 § 6.6.3 第 1 段规定“不嵌套在其中”,而 § 6.6.2 第 3 段要求“新对象的存储完全适合”。 也就是说,第 6.6.3 节第 1 段适用于一个对象未嵌套在另一个对象中的情况,而第 6.6.2 节第 3 段仅适用于一个嵌套在另一个对象中的情况。这两段不能同时适用于您的方案。
-
"虽然我没看懂前面引用的最后一条规则,但请举个例子?" 规范文本后面有例子timsong-cpp.github.io/cppwp/n4861/intro.object#3.example-1
-
数组的生命周期结束,但
int z = x[0];似乎不是UB,因为数组到指针的转换和指针运算不需要数组或其元素在其生命周期内。x[0]的生命周期并没有结束,因为它的存储没有被重用。 -
@LanguageLawyer > 指针运算不需要数组或其元素在其生命周期内您能指出标准中的规则吗? >并且 x[0] 的生命周期还没有结束,因为它的存储没有被重用你暗示当一个对象结束它的生命周期时,子对象继续存在......标准中是否有规定这种情况的规则?
标签: c++ arrays c++17 language-lawyer lifetime