为什么新变量的初始化本身有效?

时间:2015-01-26 14:41:04

标签: c++ initialization undefined-behavior variable-declaration

考虑一些代码:

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

一样编写
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;

现在我的问题是:为什么这种语法有效?为什么编译器不会说“未定义变量a”?

1 个答案:

答案 0 :(得分:11)

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

这样的狡猾的初始化
void *p = &p;

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

它的行为无效,因为使用未初始化对象的值会产生未定义的行为。这不是一个需要诊断的错误(因为,一般来说,分析程序流以查看对象是否已初始化可能很困难或不可能),但正如您所指出的,许多编译器会发出警告像这样直截了当的案例。