传递局部变量(C++)

Jef*_*one 8 c++ local-variables

我在学习C++时遇到了一个问题,其中函数中的局部变量被传递给另一个函数中具有相同名称的局部变量,这两个函数都在main()中运行.

当这个运行时,

#include <iostream>
using namespace std;

void next();
void again();

int main()
{
    int a = 2;
    cout << a << endl;
    next();
    again();
    return 0;
}

void next()
{
    int a = 5;
    cout << a << endl;
}

void again()
{
    int a;
    cout << a << endl;
}
Run Code Online (Sandbox Code Playgroud)

它输出:

2
5
5
Run Code Online (Sandbox Code Playgroud)

我期望again()会说null或0,因为'a'再次在那里声明,但它似乎使用了'a'在next()中赋值的值.

为什么next()将局部变量'a'的值传递给again()如果'a'再次在again()中声明?

moc*_*att 7

http://en.cppreference.com/w/cpp/language/ub

你是对的,一个未初始化的变量是禁忌.但是,您可以声明一个变量,直到稍后才初始化它.内存被保留以容纳整数,但是在你执行此操作之前,该内存中的值恰好可以是任何东西.有些编译器会自动将变量初始化为垃圾值(以帮助您捕获错误),有些将自动初始化为默认值,而有些则根本不执行任何操作.C++本身没有任何承诺,因此它是未定义的行为.在您的情况下,使用您的简单程序,可以很容易地想象编译器如何创建汇编代码,重复使用完全相同的内存而不改变它.然而,这是盲目的运气,即使在你的简单程序中也不能保证会发生.这些类型的错误实际上可能是相当隐蔽的,因此请将其作为规则:对未初始化的变量保持警惕.


Che*_*Alf 5

*内置类型的未初始化的非static局部变量(phew!是一口)具有不确定的值.除了类型之外,使用该值产生正式的未定义行为,即UB.任何事情都可能发生,包括你看到的行为.char

显然,使用你的编译器和选项,a调用时使用的堆栈区域在调用之前next没有被用于其他东西again,之后它被重用于ain again,现在具有与之前相同的值.

但你不能依赖它.对于UB,任何事情都可能发生.


*或更普遍的POD类型,Plain Old Data.标准的规范有点复杂.在C++ 11中,它从§8.5/ 11开始,"如果没有为对象指定初始化器,则对象是默认初始化的; 如果没有执行初始化,则具有自动或动态存储持续时间的对象具有不确定的值." 其中"自动...存储持续时间"包括局部非static变量的情况.并且通过§8.5/ 6定义默认初始化的两种方式可以发生"无初始化",即通过无操作默认构造函数,或通过不属于类或数组类型的对象.