C++ 在自己的初始值设定项中使用变量
在C++20标准草案的注释中有以下(非规范性)示例(合并前的部分引用,请参阅此问题的答案): […]x用它自己的(不确定)值初始化 在C++20中,这实际上有定义良好的行为吗C++ 在自己的初始值设定项中使用变量,c++,initialization,language-lawyer,lifetime,c++20,C++,Initialization,Language Lawyer,Lifetime,C++20,在C++20标准草案的注释中有以下(非规范性)示例(合并前的部分引用,请参阅此问题的答案): […]x用它自己的(不确定)值初始化 在C++20中,这实际上有定义良好的行为吗 通常,表单的自初始化tx=x具有未定义的行为。计算不确定值通常会导致未定义的行为(),但有一个特殊的例外,即允许直接从具有不确定值的左值无符号字符初始化无符号字符变量(导致具有不确定值的初始化) 因此,这本身不会导致未定义的行为,但会导致非无符号窄字符类型或std::byte的其他类型的行为,例如int x=x。这些注意
通常,表单的自初始化
tx=x由于在初始化完成之前,x
的值是不确定的,因此code>具有未定义的行为。计算不确定值通常会导致未定义的行为(),但有一个特殊的例外,即允许直接从具有不确定值的左值无符号字符
初始化无符号字符
变量(导致具有不确定值的初始化)
因此,这本身不会导致未定义的行为,但会导致非无符号窄字符类型或std::byte
的其他类型的行为,例如int x=x代码>。这些注意事项也适用于C++17及其之前的版本,另请参见底部的链接问题
然而,即使对于无符号字符x=x代码>,当前草案的内容是:
类似地,在对象的生存期开始[…]之前,使用不依赖于其值的glvalue的属性是定义良好的。在以下情况下,程序具有未定义的行为:
- glvalue用于访问对象,或
- [……]
这似乎意味着示例中的x
值只能在其生命周期内使用
说:
[……]
类型为T的对象的生存期始于:
- [……]和
- 其初始化(如果有)已完成(包括真空初始化)([dcl.init])
[……]
因此,x
的生命周期只有在初始化完成后才开始。但是在引用的示例中,x
的值是在x
初始化完成之前使用的。因此,使用具有未定义的行为
我的分析是否正确?如果正确,是否会影响初始化前的类似使用情况,例如
int x = (x = 1);
据我所知,在C++17及之前的版本中,哪些是定义良好的
请注意,在C++17(最终草案)中,生命周期开始的第二个要求是:
- 如果对象具有非空初始化,则其初始化已完成
由于根据C++17的定义,x
将具有真空初始化(但不是当前草案中的定义),因此在上面给出的示例中,当在初始化器中访问它时,它的生存期就已经开始了,因此在这两个示例中,由于C++17中的x
的生存期,没有未定义的行为
C++17之前的措辞也有所不同,但结果相同
该问题与使用不确定值时的未定义行为无关,如以下问题中所述:
这是作为一个文件打开的。它被转发给CWG进行(内部)讨论。大约24小时后,转发问题的人修改了示例,以明确这是UB:
这里,第二个\t代码{x}的初始化具有未定义的行为,因为初始值设定项在其生存期\iref{basic.life}之外访问第二个\t代码{x}
该公关已被添加,问题已结束。因此,显而易见的解释(由于访问一个生命周期尚未开始的对象而导致的UB)就是预期的解释。似乎委员会的目的是使这些结构不起作用,标准的非规范性文本已经更新以反映这一点。@language律师我不相信我是正确的,尤其是如果没有人回答的话。如果其他人在这里同意我的意见,我可能会稍后提交一份(或者其他人会在我之前提交),但我不想提交我不确定的问题。@language律师:如果工作文件明确地说了错误的话,这不可能是一个编辑问题。这个词被更改了。@xskxzr Right,同时,律师还提交了一份申请,似乎已转交给CWG澄清意图。@clockw0rkint x^=x代码>的语法格式不正确。您可以使用带有初始值设定项的变量定义(即int x=x;
,尽管它是UB)或xor赋值表达式语句(即x^=x;
,尽管它是UB,如果x
的类型是int
,则它是默认初始化的,并且事先没有赋值)。你不能把这两者混为一谈。
int x = (x = 1);