问题描述
考虑一些代码:
#include <iostream>
int main()
{
using std::cout;
int a=3;
cout << "a="<<a<<"\n";
{
int a=a;
cout << "new a = " << a << "\n";
a=5;
cout << "a = " << a << "\n";
}
cout << "old a = " << a << "\n";
}
我希望它打印
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;
所以我的问题现在:为什么这个语法有效?为什么编译器不说undefined variable 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.
这篇关于为什么一个新变量的初始化本身有效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!