在c ++中std :: cout的奇怪行为

时间:2013-10-07 18:16:04

标签: c++ expression std operator-precedence expression-evaluation

#include <iostream>

int a(int &x) {
    x = -1;
    return x;
}

int main () {
    int x = 5;
    std::cout << a(x) << " " << x << std::endl;
}

为什么输出为“-1 5”?

PS:编译器是:

i686-apple-darwin11-llvm-g ++ - 4.2(GCC)4.2.1(基于Apple Inc. build 5658)(LLVM build 2336.11.00)

PS:没有任何优化编译。

3 个答案:

答案 0 :(得分:14)

在这一行:

std::cout << a(x) << " " << x << std::endl;

未指定a(x)x的评估顺序。这是未指定的行为,在您的情况下,编译器决定先评估x,然后再评估a(x)

答案 1 :(得分:3)

正在评估a(x)x的订单是 未指定 [1] 的。为了确保x不会在同一个表达式中被修改(并通过这样做避免未指定的行为),你可以这样做:

int x = 5;
int y = a(x);
std::cout << y << " " << x << std::endl;

[1] “除非另有说明,否则单个运算符的操作数和各个表达式的子表达式的评估顺序以及副作用发生的顺序是未指定的。” 5表达式,§4

答案 2 :(得分:1)

评估顺序未经过排序,因此unspecified behavior可以首先评估a(x)x。关于C++ draft standard部分1.9 计划执行 15 说(强调我的):

  

[...] 除非另有说明,否则对单个运算符的操作数和单个表达式的子表达式的评估是不确定的。 [注意:在程序执行期间不止一次评估的表达式中,不需要在不同的评估中一致地执行对其子表达式的未序列和不确定顺序的评估。 - 尾注] [...]

它甚至可能在不同的评估之间有所不同,如果我们回到段落 13 它会说:

  

[...] 如果在A之前未对A进行排序,而在A之前未对B进行排序,则A和B未被排序。 [注意:未经测试的评估的执行可能会重叠。 -end note]评估 A和B是不确定的测序当A在A之前测序或B在B之前测序,但是未指定哪个。[...]

这解释了这是未指明的行为。