4
#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:编译没有任何优化。

4

3 回答 3

15

在这一行:

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

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

于 2013-10-07T18:17:52.393 回答
3

评估a(x)和的顺序未指定[1]。为确保不会在同一表达式中修改(并通过这样做避免未指定的行为),您可以执行以下操作:xx

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

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

于 2013-10-07T18:21:18.537 回答
1

评估的顺序是无序的,因此它是未指定的行为a(x),或者可以x先评估。关于C++ 草案标准部分1.9 程序执行15段说(强调我的):

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

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

[...]如果 A 没有在 B 之前排序并且 B 没有在 A 之前排序,那么 A 和 B 是 unsequenced。[注意:未排序评估的执行可以重叠。—尾注]当 A 在 B 之前排序或 B 在 A 之前排序时,评估 A 和 B 的排序不确定,但未指定哪个.[...]

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

于 2013-10-07T18:38:55.637 回答