为什么这个没有编译错误?

6
int a = a ;  

根据赋值运算符的规则,应该从右到左读取该行。 在看到'a'未声明后,编译器应该给出编译错误。
但是,它却给出了垃圾值。请澄清一下。

这实际上不会允许使用垃圾值声明 a,然后可能打印出该垃圾值吗?根据您的逻辑,声明中将无法分配任何内容。int a = 1; 将失败,因为赋值“从右到左”进行,因此 a 未声明;是吗? - ChiefTwoPencils
3
由于您从未初始化a,因此现在它仍然是最初存在的垃圾值。 - dandan78
可能是Is self-initialization 'A a = a;' allowed? 的重复。还有一个相似的问题:https://dev59.com/fk7Sa4cB1Zd3GeqP69fL - jogojapan
1
@jagojapan:我的问题是为什么这个代码没有编译错误。因为在赋值时'a'未声明。但这个问题仍然没有得到解答 :( - rforritz
@rforritz 我认为你会喜欢阅读这篇简短的笔记:声明点,以了解编译器为什么不会报错。 - Grijesh Chauhan
2个回答

10

§3.3.2/1:

名称的声明点是在其完整声明符(第8条款)之后、其初始化程序(如果有)之前。但如下所述除外。【例如:

int x = 12;
{ int x = x; }

这里第二个 x 的值会被初始化为自己的(不确定的)值。— 示例结束]


请注意,在最新的C++1y草案中,这一点已经改变 - Shafik Yaghmour

2

实际上,编译器可能会给你一些提示。我的说:"警告C4700:局部变量'a'在使用时没有被初始化"。

但是这并不是一个错误,声明只是为某些内存位分配了变量名而没有操作它,这是有效且快速的。这里的赋值也不是真正的赋值,只是将位从右移动到左。没有任何检查,非常高效但也非常不安全。

每个操作都是合法的,但整个过程毫无意义。所以编译器尽其所能——编译代码,但也发出了警告。


1
初始化并不是“仅仅给一些内存位一个变量名而不触及它”的过程。声明才是这样的过程。初始化是为那个被命名的内存位提供初始值的步骤。 - This isn't my real name
是的,完全正确。但在这种情况下基本上没有初始化。看起来像是一个初始化的地方实际上只是一个声明和赋值。 - akalenuk
哦,我可能应该编辑我的答案以避免混淆。谢谢! - akalenuk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接