可能重复:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)
在Java中,评估顺序指定为从左到右。这是C和C ++的情况,还是依赖于实现?我确实记得评估顺序没有指定函数参数,但是子表达式呢?
答案 0 :(得分:14)
未指定+
的哪个参数首先被评估 - 但这甚至不重要,因为在C和C ++中,在没有插入序列点的情况下两次修改同一个对象是完全未定义的行为。 / p>
此处您正在修改x
三次次而没有插入序列点,因此您可以很好地进入此处为dragonnes 区域;)
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;
}
(未指定是否获得foobar
或barfoo
的输出。
答案 1 :(得分:4)
C ++ 03 Standard 5.4
除非另有说明,否则顺序为 评估个人的操作 运算符和子表达式 个人表达和秩序 发生副作用的是 未指定.5)之前的 下一个序列指向一个标量 对象应具有其存储值 最多修改一次 表达的评价。 此外,先前的值应为 只访问以确定值 要存储。这个要求 应满足每一段 允许的订购 表达式的子表达式; 否则行为未定义。
...因此,未定义和依赖于实现。
答案 2 :(得分:3)
C标准并不保证后增量实际上会在预增量后“发生”。这是未定义的行为。
答案 3 :(得分:2)
这不是一个有效的C语句,所以谈论评估顺序是没有意义的。