2010-03-03 68 views
8

可能重复:在Java中指定的评估顺序为左到右
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)x = x ++ + ++ x的评估顺序是什么?是?

。 C和C++也是如此,还是依赖于实现?我确实记得评价顺序对函数参数没有指定,但子表达式又如何?

+0

Duplicates:http://stackoverflow.com/questions/949433/could-anyone-explain-these-undefined-behaviors-iiiii-etc http://stackoverflow.com/questions/1826414/whats-the-value-关闭 - 关闭http://stackoverflow.com/questions/1788696/how-the-code-behaves-different-for-java-and-c-compiler – bk1e

+18

大声笑。 mod mod关闭了他自己的问题:D – Earlz

+3

@ bk1e:感谢您的链接。我有一种感觉,前面会介绍这个,但是当我问这个问题时,它并没有出现。我认为找到原创的最快捷方式就是问问。 :) –

回答

13

没有指定+的哪个参数首先被计算 - 但这甚至不重要,因为在C和C++中,修改相同的对象两次而没有插入的序列点是完全未定义的行为。

在这里,我们修改x 次中间没有顺序点,所以你富裕的保留;)


C99标准的相关部分是“6.5表达式”:

2之前和下一 序列点对象所通过的评价至多一次 改性 其存储的值之间表达。 此外,先前值应为 只读,以确定存储的值为 。

3运算符和操作数 的分组是由 语法表示。除非以后指定 (用于函数调用(),& &,||,?, 和逗号运营商),子表达式的 评价的顺序和 顺序副作用发生 都是不确定。


有可能写演示评价的指定顺序法典 - 例如:

#include <stdio.h> 

int foo(void) 
{ 
    puts("foo"); 
    return 1; 
} 

int bar(void) 
{ 
    puts("bar"); 
    return 2; 
} 

int main() 
{ 
    int x; 

    x = foo() + bar(); 
    putchar('\n'); 

    return x; 
} 

(你是否得到foobarbarfoo输出这是不确定的)。

+0

感谢您的快速回复。 –

2

C标准并不保证后增量实际上会在预增量后“发生”。所以这是未定义的行为。

1

这不是一个有效的C语句,因此谈论评估顺序是没有意义的。

+1

“有效”是什么意思?它成功编译在gcc和g ++中。 –

+4

gcc是否成功编译文件与它是否包含有效的C语句无关。 C标准确定什么是有效的C,而不是一个编译器。 –

+4

此语句在语法上有效,但语义不正确,因为它会导致未定义的行为。 – qrdl

3

C++ 03 Standard 5。4

除非另有说明, 评估个体 运营商和 单个表达式的子表达式的操作数,并 其中副作用发生的顺序的顺序,是 unspecified.53)先前 之间并且下一个序列点标量为 的对象的储值 最多会被表达式的 评估修改一次。 此外,先前的值应为 ,仅用于确定要存储的值 。这个 段落的要求应该满足每个 允许的 子表达式的完整表达式; 否则行为是未定义的。

...因此,未定义和实现相关。

相关问题