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

标签 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;

那么我现在的问题是:为什么这个语法完全有效?为什么编译器不说“ undefined variable a”之类的东西?

最佳答案

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

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

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

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

关于c++ - 为什么单独初始化一个新变量是有效的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28152298/

相关文章:

java - 在java中的for循环中初始化对象?

c++ - 如何静态初始化包含 union 的结构数组?

c++ - func() + func() 是未定义的行为吗?

c++ - 将 long long 转换为 int 如何工作?

c++ - C++中的前向声明

machine-learning - 手工制作的 Xavier 初始化器 : Which values for lrelu and relu

c - 是什么导致此代码仅适用于某些编译器(UD?)?

c++ - 在此上下文中的完美转发和 std::move 行为

c++ - QMessageLogContext 的字段(如 : file, 函数、行)为空或为零

c++ - 一些未定义的行为是否比其他行为更未定义?