2012-06-21 35 views
9

我有我的大脑从试图了解此页面上的例子皱: http://answers.yahoo.com/question/index?qid=20091103170907AAxXYG9C++和Java之间的表达式评估顺序如何不同?

更具体地说,本代码:

int j = 4; 
cout << j++ << j << ++j << endl; 

给出了一个输出:566

现在,这是有道理的对我来说,如果表达式是从右到左评估的,然而在Java中有类似的表达式:

int j = 4; 
System.out.print("" + (j++) + (j) + (++j)); 

给出的输出:456

哪一个更直观的,因为这表明它已经从左向右计算。在各种网站上研究这一点,似乎用C++编译器之间的行为有所不同,但我仍然不相信自己明白。 Java和C++之间评估的这种差异有什么解释?感谢所以。

+2

一切都不一样。它不仅在编译器之间不同,而且还依赖于rules_,并且每次在同一个编译器上进行编译时,每次运行该程序时,甚至每次执行该行时都会发生变化。的 –

+0

可能重复的[如何未定义是未定义的行为?](http://stackoverflow.com/questions/7961067/how-undefined-is-undefined-behavior) –

+1

C++被设计为最优化,这意味着标准不保证某些结果,以便编译器可以自由地生成最优代码。您在示例中使用的序列是我认为明确禁止的序列。 –

回答

11

当操作有副作用,C++依赖于sequence points规则来决定何时副作用(如增量,组合分配等)具有生效。逻辑and-then/or-else&&||)运算符,三元?问号运营商,和逗号创建序列点; +,-,<<等都没有。

相反,Java在继续进行进一步评估之前完成副作用。

当使用具有副作用的表达在不存在的序列点多次,将得到的行为是在C++中未定义的。任何结果都是可能的,包括一个没有逻辑意义的结果。

3

在C++中,子表达式的评估顺序不是从左到右,也不是从右到左。这是undefined

5

Java保证操作符的操作数看起来是按照特定的评估顺序进行评估的,即从左到右。二元运算符的左侧操作数在评估右侧操作数的任何部分之前似乎已经完全评估。 Java还保证在执行操作的任何部分之前,运算符的每个操作数(除条件运算符&&||?:之外)似乎都被完全评估。有关更多详细信息,请参阅Java语言规范第15.7节。

C++,在另一方面,高高兴兴地让你得逞的未定义行为,如果表达不明确,因为语言本身并不能保证子表达式的求任何顺序。有关更多详细信息,请参阅Sequence Point