变量定义中的自赋值 下面的C++程序编译得很好(G++ 5.4至少在调用墙>代码>时给出警告:

变量定义中的自赋值 下面的C++程序编译得很好(G++ 5.4至少在调用墙>代码>时给出警告:,c++,C++,甚至像 int& p = p; 被编译器吞没 现在我的问题是:为什么这样的初始化是合法的?是否存在任何实际用例,或者它只是语言总体设计的结果?仅仅因为编译器接受它(语法上有效的代码),并不意味着它具有定义良好的行为 编译器不需要诊断所有未定义的行为或其他类型的问题。 该标准允许它非常自由地接受和翻译损坏的代码,前提是如果结果未定义或无意义,程序员就不会编写该代码 所以,;编译器中没有警告或错误并不证明程序具有定义良好的行为。 遵守语言规则是你的责任。 编译器通常试图通过指出明显的缺陷来

甚至像

int& p = p;
被编译器吞没


现在我的问题是:为什么这样的初始化是合法的?是否存在任何实际用例,或者它只是语言总体设计的结果?

仅仅因为编译器接受它(语法上有效的代码),并不意味着它具有定义良好的行为

编译器不需要诊断所有未定义的行为或其他类型的问题。 该标准允许它非常自由地接受和翻译损坏的代码,前提是如果结果未定义或无意义,程序员就不会编写该代码

所以,;编译器中没有警告或错误并不证明程序具有定义良好的行为。 遵守语言规则是你的责任。 编译器通常试图通过指出明显的缺陷来帮助您,但最终还是由您来确保您的程序有意义


类似于
inti=i
没有意义,但语法正确,因此编译器可能会警告您,也可能不会警告您,但在任何情况下,它都有权只生成垃圾(而不是告诉您)因为您违反了规则并调用了未定义的行为。

我想您问题的要点是关于为什么在
int I=I
int&p=p

这在C++14标准的[basic.scope.pdecl]/1中定义:

名称的声明点紧跟在其完整声明符之后和其初始值设定项(如果有)之前,除非如下所述。[示例:

unsigned char x = 12;
{ unsigned char x = x; }
这里,第二个
x
用它自己的(不确定)值初始化。-结束示例]

这些语句的语义包含在其他线程中:

注-引用的示例在语义上不同于
int i=i无符号字符
,而是UB来计算未初始化的
int

正如链接线程上所指出的,g++和clang在检测到这一点时会发出警告


关于范围规则的原理:我不确定,但是C中存在的范围规则,也许它只是进入了C++,现在改变它会很混乱。


如果我们说声明的变量不在其初始值设定项的范围内,那么
int i=i
可能会使第二个
i
从外部作用域中找到一个
i
,这也会造成混淆。

这是一个规则的副作用,即名称在声明后立即进入作用域。没有必要为了防止编写明显无意义的代码而使这个简单规则复杂化。

相关和
inti=i
应该抑制关于使用未初始化变量的警告,但它使用未初始化变量来初始化变量,这实际上不是一种改进。
int&p=p看起来很奇怪;我很惊讶,我在这里发表了评论,我在这里看到了两个问题。(1) 为什么
i
在定义
i
的语句的初始值设定项中出现时,它是一个已定义的变量?以及(2)为什么C++允许未初始化变量在初始化器中使用(或者,在任何其他地方都适用)?@ JonathanLeffler,没有规则明确禁止它;允许
int&p=q
int&r=p
allow
int&p=p
,其中
q
是类型
int
和类别左值的表达式。变量的声明符一完成(即在任何初始值设定项之前),变量就在范围内,
int&p
表示
p
具有type
int
和category lvalue.OK,但
int i=xx
,那么code>在语法上是不正确的,那么为什么语句
inti=i视为正确?也就是说,
I
声明在声明
I
的语句中可见的原因是什么?@jameslarge:
I
int I
末尾完成(但未初始化);
=i正在引用一个已定义(但未初始化)的变量;i=i@jameslarge一个可能的原因是允许使用静态函数的返回值从它自己的类初始化变量:
LongClassName x=x.static_func()
而不是
LongClassName x=LongClassName::static_func()
unsigned char x = 12;
{ unsigned char x = x; }