为什么新变量的初始化本身是有效的?
考虑一些代码:
#include <iostream>
int main()
{
using std::cout;
int a=3;
cout << "a="<<a<<"
";
{
int a=a;
cout << "new a = " << a << "
";
a=5;
cout << "a = " << a << "
";
}
cout << "old a = " << a << "
";
}
我希望它打印出来
a=3
new a = 3
changed a = 5
old a = 3
但实际上我得到的似乎是第二行中的 new a = 0
.我认为它会像类的构造函数中的初始化列表一样工作,可以像这样写
But what I get actually appears to say new a = 0
in the second line. I thought that it would work like initialization list in a class' constructor, where one can write like
C::C(int a) : a(a) {}
但由于某种原因,情况有所不同.首先,完全删除外部代码不会导致编译错误.所以我假设 int a=a;
是有效的.打开所有编译器警告会导致:
But for some reason this is different. First, removing the outer code completely doesn't result in a compilation error. So I assume that int a=a;
is valid. Turning on all the compiler warnings leads to this:
test.cpp: In function ‘int main()’:
test.cpp:10:15: warning: ‘a’ is used uninitialized in this function
int a=a;
所以我现在的问题是:为什么这种语法完全有效?为什么编译器不说未定义的变量a"之类的东西?
So my question now: why is this syntax valid at all? Why doesn't the compiler say something like "undefined variable a"?
推荐答案
它在语法上是有效的,因为变量的声明点在它的初始化器之前,并且名称在该点之后的任何地方都可用.这允许像
It's syntactically valid, since the variable's point of declaration comes before its initialiser, and the name is available anywhere after that point. This allows less dodgy initialisations like
void *p = &p;
合法地使用正在初始化的变量的名称(但不是值).
which legitimately uses the name (but not the value) of the variable being initialised.
它在行为上是无效的,因为使用未初始化对象的值会产生未定义的行为.这不是需要诊断的错误(因为一般来说,分析程序流以查看对象是否已初始化可能很困难或不可能),但正如您所注意到的,许多编译器会对像这样的简单情况发出警告.
It's behaviourally invalid, since using the value of an uninitialised object gives undefined behaviour. That's not an error that requires diagnosis (since, in general, it can be difficult or impossible to analyse the program flow to see whether an object has been initialised), but as you note, many compilers will give a warning for straightforward cases like this.
相关文章