传递未初始化的变量安全

Passing uninitialized variables safety

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

#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?

can I say for sure that x will always be initialized before printvals uses it?

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

的副作用

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

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

如果你敢阅读,请参阅标准 "standardese" :)

PS:即使可能已经指定了顺序,避免这样的代码始终是个好主意,因为大多数时候阅读您的代码的其他人都会有完全相同的问题,并且会浪费很多时间去挖掘。只是更喜欢清晰度而不是极其 "clever" 代码。

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

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

The order of evaluation of function arguments is unspecified.

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