传递未初始化的变量安全

Passing uninitialized variables safety

本文关键字:变量 安全 初始化      更新时间:2023-10-16

我今天偶然发现了一些代码,我将其简化为:

#include <iostream>
using std::cout;
using std::cin;
bool changeX(int &x)
{
    x = 5;
    return true;
}
void printvals(bool bval, int intval)
{
    cout << bval << " : " << intval;
}
int main()
{
    int x;
    printvals(changeX(x), x);
    cin.get();
}

在这里,x在传递给函数时仍未初始化printvals但我可以肯定地说 x 在 printvals 使用它之前将始终被初始化吗?我尝试在VS2013调试模式下运行简化的代码,这给了我:Run-Time Check Failure #3 - The variable 'x' is being used without being initialized.。但是,在发布模式下运行它运行良好并打印:1 : 5按预期。

这是否意味着我可以在生产代码中使用此方法?x是否总是在printvals可以使用它之前进行初始化,这样它就不会导致 UB?

我可以肯定地说x在使用它之前printvals总是被初始化吗?

否,未指定函数参数的计算顺序。由于您可能从未初始化的变量中读取,因此您的代码可能具有未定义的行为。您不能依赖调用changeX的副作用。

函数中参数的求值顺序未指定,所以不,你不能这么说。

例如 http://en.cppreference.com/w/cpp/language/eval_order

或者如果你敢读"标准":),就看标准

PS:即使可能已经指定了顺序,避免这样的代码总是一个好主意,因为大多数时候阅读您的代码的其他人会遇到完全相同的问题,并且会浪费大量时间深入研究。只是更喜欢清晰而不是极其"聪明"的代码。

这可能会导致未定义的行为,因为执行顺序未指定(这取决于编译器)。

这是C++标准非常容易理解的地方之一。从 §8.3.6/9(在 N3797 中,强调我的):

未指定函数参数的计算顺序。

这意味着您不能依赖在调用changeX()后将intval评估为x的副本。因此,您的代码是未定义的行为。