wal*_*nut 23 c++ initialization lifetime language-lawyer c++20
C++20 标准草案的[basic.scope.pdecl]/1在注释中包含以下(非规范性)示例(合并拉取请求 3580之前的部分引用,请参阅此问题的答案):
unsigned char x = x;
Run Code Online (Sandbox Code Playgroud)
[...] x 用它自己的(不确定的)值初始化。
这实际上在 C++20 中有明确定义的行为吗?
通常T x = x;,由于x的值在初始化完成之前是不确定的,因此表单的自初始化具有未定义的行为。评估不确定的值通常会导致未定义的行为([basic.indent]/2),但在[basic.indent]/2.3中有一个特定的例外,它允许直接unsigned char从unsigned char具有不确定值的左值初始化变量(导致使用不确定值初始化)。
这本身并不会因此导致不确定的行为,但会为其他类型T不属于无符号窄字符类型或std::byte如int x = x;。这些注意事项也适用于 C++17 及之前的版本,另请参阅底部的链接问题。
然而,即使对于unsigned char x = x;,当前草案的[basic.lifetime]/7说:
类似地,在对象的生命周期开始之前 [...] 使用不依赖于其值的泛左值的属性是明确定义的。在以下情况下,程序具有未定义的行为:
泛左值用于访问对象,或
[...]
这似乎意味着x示例中的that值只能在其生命周期内使用。
[...]
类型 T 的对象的生命周期在以下情况下开始:
- [...] 和
- 它的初始化(如果有)完成(包括空初始化)([dcl.init]),
[...]
因此x的生命周期仅在初始化完成后才开始。但是在引用的例子中x的值是在x初始化完成之前使用的。因此,使用具有未定义的行为。
我的分析是否正确,如果正确,是否会影响类似的使用前初始化的情况,例如
int x = (x = 1);
Run Code Online (Sandbox Code Playgroud)
据我所知,在 C++17 及之前的版本中,哪些是明确定义的?
请注意,在 C++17(最终草案)中,生命周期开始的第二个要求是不同的:
- 如果对象有非空初始化,则其初始化完成,
由于xC++17 的定义(但不是当前草案中的定义)会进行空初始化,因此在上面给出的示例中的初始化程序中访问它时,它的生命周期已经开始,因此在两个示例中都没有未定义的行为由于x在 C++17 中的生命周期。
C++17 之前的措辞再次不同,但结果相同。
问题不在于使用不确定值时的未定义行为,例如以下问题中的内容:
| 归档时间: |
|
| 查看次数: |
637 次 |
| 最近记录: |