是 int &ref = ref;结构良好

Is int &ref = ref; well formed

提问人:Alan 提问时间:11/10/2023 最后编辑:user12002570Alan 更新时间:11/10/2023 访问量:1128

问:

我了解到,评估未初始化的变量是未定义的行为。特别是,是未定义的行为。我已阅读 用作其自己的初始值设定项的未初始化变量的行为是什么?int i = i;

但是,使用引用变量初始化自身是否也是未定义的行为?特别是,按照 C++ 标准,UB 也是吗?int &ref = ref;

int &ref = ref; // Is this well-formed or ill-formed or UB

所有编译器都编译上述程序(clang 发出警告)。这是因为它是未定义的行为,所以任何事情都允许发生,还是程序格式良好?


此外,如果我要为 分配一些值,程序的行为会与前一种情况不同吗?ref

int &ref = ref;

int main()
{
    ref = 1; //does this change the behavior of the program from previous case
}

我注意到,对于第二个代码段,我们得到了一个段错误。

我读过的一些参考资料是:

用作其自己的初始值设定项的未初始化变量的行为是什么?

为什么初始化新变量本身是有效的?

C++ 参考 语言-律师 自初始化

评论

4赞 foragerDev 11/10/2023
是的,这是未定义的行为,如果不初始化它,您就不能使用引用。
0赞 foragerDev 11/10/2023
最有可能的是,你的程序会给你SIG FAULT。
2赞 Alan 11/10/2023
@foragerDev 你能给我一个 c++ 标准的参考吗?不,它不会给出 seg 错误。
1赞 user12002570 11/10/2023
@foragerDev 第一个片段演示没有 seg 错误。另请注意,问题是语言律师int &ref = ref;
0赞 foragerDev 11/10/2023
@Alan在初始化引用变量之前使用引用变量是一种未定义的行为。语言没有定义任何东西,你的程序会做什么。您可以在此处看到以下内容:godbolt.org/z/T6Ks61ajK

答:

25赞 Artyer 11/10/2023 #1

它不是定义的行为。

[dcl.ref]p5

[...]应初始化引用以引用有效的对象或函数。

并且没有对象可参考。int


您也可以说该引用在其生存期之外使用。

[basic.life]

  1. 引用的生存期从其初始化完成时开始。引用的生存期结束,就好像它是需要存储的标量对象一样。

  2. 本文档中归因于对象和引用的属性仅适用于给定对象或引用的生存期。

因此,在引用本身初始化之前,不能“使用”引用来初始化自身,这就是 Clang 对此的抱怨(https://godbolt.org/z/Ea4qPoWbs):

note: use of reference outside its lifetime is not allowed in a constant expression
    2 |     int& ref = ref;
                       ^

评论

1赞 Language Lawyer 11/10/2023
为什么不提 cplusplus.github.io/CWG/issues/453
0赞 Artyer 11/10/2023
@LanguageLawyer 该措辞似乎暗示应该格式不正确const size_t& s = sizeof(s);
1赞 Ben Voigt 11/10/2023
@Artyer:因为是一个未计算的上下文,所以它不依赖于所提到的任何对象的生存期。事实上,它只关心表达式的类型,而不关心它的值或标识。但是,是的,对“名称”的限制似乎是错误的。可能“使用”是关键,在标准术语中可能具有狭义的含义。sizeof