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

Why is initialization of a new variable by itself valid?

本文关键字:初始化 有效 新变量 变量 为什么      更新时间:2023-10-16

考虑一些代码:

#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"之类的东西?

它在语法上是有效的,因为变量的声明点在其初始化器之前,并且该名称在该点之后的任何位置都可用。这允许不那么狡猾的初始化,例如

void *p = &p;

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

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