假设你在c中有x = exp1 + exp2。可以通过首先评估exp1然后exp2并添加结果来评估它,但是它可以首先评估exp2。
您如何确定首先评估哪一方?我想使x = 1/2取决于首先评估哪一个。
有什么想法吗?
答案 0 :(得分:5)
好的,你可以这样做:
1
在ideone.com上,我得到()
。
请注意,这没有任何证据,因为此处没有定义的行为。 C99草案说(在6.5表达式中,第3段):
运算符和操作数的分组由表示 语法。 72 ) 除非稍后指定(对于函数调用
&&
,||
,?:
, 子表达式和表达式的评估顺序public static class MyClass { public static string Foo = "foo"; public static string Barbaz = "bar baz"; }
和逗号运算符 副作用发生的顺序都是未指定的。
答案 1 :(得分:0)
如何确定首先评估哪一方?
通常这不是标准规定的。 C11 6.5 / 3:
除了后面指出的,副作用和价值计算 子表达式没有排序。 86)
...
86)在多次评估的表达式中 在执行程序期间,无序和不确定 不需要执行其子表达式的有序评估 始终如一地进行不同的评估。
“稍后指定”是指一些特殊情况,其中指定了评估顺序,即对于以下运算符:|| && ?: ,
,它们都保证从左到右进行评估。
正如我们从引用的注释中可以看到的,我们甚至无法知道相同的程序是否会一致地对待相同的表达式。这称为未指定的行为,这意味着编译器将以几种明确定义的方式之一运行,但我们永远不会知道或假设哪种方式。您应该始终编写程序,以便评估顺序无关紧要。
如果您希望使用代码打印出编译器决定评估特定表达式的次序(这次),您可以这样做:
#include <stdio.h>
int func(void)
{
static int x=0;
return x++;
}
int main (void)
{
printf("%d", func() << func());
}
这将提供0<<1 == 0
(从左到右)或1<<0 == 1
(从右到左)。但是这样的代码没有实际意义。