为什么单独初始化一个新变量是有效的?

Why is initialization of a new variable by itself valid?

考虑一些代码:

#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。我认为它会像 class' 构造函数中的初始化列表一样工作,其中可以写成

C::C(int a) : a(a) {}

但出于某种原因,这是不同的。首先,完全删除外部代码不会导致编译错误。所以我假设 int a=a; 是有效的。打开所有编译器警告会导致:

test.cpp: In function ‘int main()’:
test.cpp:10:15: warning: ‘a’ is used uninitialized in this function
         int a=a;

所以我现在的问题是:为什么这个语法完全有效?为什么编译器不说 "undefined variable a"?

它在语法上是有效的,因为变量的声明点在其初始化程序之前,并且该名称在该点之后的任何地方都可用。这允许像

这样的不可靠的初始化
void *p = &p;

合法使用被初始化变量的名称(但不是值)。

它在行为上是无效的,因为使用未初始化对象的值会产生未定义的行为。这不是需要诊断的错误(因为通常很难或不可能分析程序流以查看对象是否已初始化),但正如您所注意到的,许多编译器会对像这样的简单情况发出警告.