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”?C++中std :: cout的奇怪行为

PS:编译器是:

的i686-苹果darwin11-LLVM-G ++ - 4.2(GCC)4.2.1(基于苹果公司建立5658)(LLVM建立2336.11.00)

PS:编译没有任何优化。

+0

这些标准术语是功能副作用 – fayyazkl

回答

14

在这一行:未指定

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

a(x)x评价的顺序。这是没有说明的行为会发生什么,在你的情况下,编译器决定先评估x,然后评估a(x)

+4

它是*未定义的行为*?我认为这是*未指定的行为*。 – Nawaz

+0

@Nawaz Hm,可能是未指定的行为(§1.3.15)我认为。编辑。 –

+0

这在我看来很奇怪,因为函数已经工作了。我希望内存中单元格的值可以改变。也许有人可以解释我如何在asm代码中翻译? –

3

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

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

[1] “除非另有说明,评价的顺序个体经营者和单个表达式的子表达式,并且其中的副作用发生的顺序的操作数,是未指定“。5表达式,§4

+2

我认为它是*未指定*,而不是*未定义*。 – Nawaz

+0

@Nawaz:你是对的:) – LihO

1

评估顺序未确定,因此可以先评估0​​或者a(x)x。关于C++ draft standard部分1.9程序执行款说(重点煤矿):

[...] 除非另有说明,个体经营者的操作数和各个子表达式的评估表达式不确定。 [注意:在一个程序执行过程中多次评估的表达式中,对其子表达式的无序和不定序评估不需要在不同的评估中一致地执行。末端注] [...]

,它甚至可以在不同的评价和furthmore之间的差异,如果我们去回款它说:

[...] 如果A在B和B未在A之前测序之前未被测序,则A和B未测序。 [注意:不确定评估的执行可能会重叠。结束注释]评估A和B是不确定的测序当A在B或B之前测序之前在A之前测序,但是未指定哪个。[...]

这说明这是未指定的行为。