C++ C+中运算符优先级的混淆+;
假设,在以下测试表达式中:C++ C+中运算符优先级的混淆+;,c++,gcc,visual-studio-2017,operator-precedence,C++,Gcc,Visual Studio 2017,Operator Precedence,假设,在以下测试表达式中: int ggg9 = fggg2() + (fggg3() && fggg4() < fggg5() * fggg6()); // 4 11 6 3 但x86-64 gcc 8.2本身: (我将把它转换回C++) 那么为什么&&操作符似乎在*之前被求值,然后你把求值顺序和操作符的优先级混淆了,虽然保证保留优先级,但求值顺序不是,编译器可以自由选择顺序 可以评估
int ggg9 = fggg2() + (fggg3() && fggg4() < fggg5() * fggg6());
// 4 11 6 3
但x86-64 gcc 8.2本身:
(我将把它转换回C++)
那么为什么
&&
操作符似乎在*
之前被求值,然后你把求值顺序和操作符的优先级混淆了,虽然保证保留优先级,但求值顺序不是,编译器可以自由选择顺序
可以评估<代码> FGGG2()/<代码>,首先在中间或在其他操作数的评估之间。
< P>您把评价顺序与操作符的优先级混淆,而保证优先顺序,评价顺序不是,编译器可以自由选择顺序。
可以评估<代码> FGGG2()/<代码>,首先在中间或在其他操作数的评估之间。
您将优先级与评价顺序混合。
这是一个相当普遍的困惑。也许是因为英语中的“prefere”这个词有时间含义。但实际上,它是指一种等级制度(例如)
在更简单的表达式a()+b()*c()
中,优先级告诉我们*
运算符的操作数是b()
和c()
,而+
的操作数是a()
和乘法的结果。不多也不少
函数a、b、c
仍然可以按任何顺序调用
确实,*
的值计算必须在+
的值计算之前进行,因为我们需要知道前者的结果才能计算后者
值计算是计算操作数的不同步骤。运算符的操作数必须在计算其值之前求值,但没有比这更严格的要求了。没有关于求值操作数偏序的规则
+
的左操作数的求值可能先于+
的右操作数,即使右操作数由许多子表达式组成。编译器可能会计算所有“叶”操作数,将结果存储在堆栈中,然后执行值计算
也不一定有严格的值计算顺序,例如在w()*x()+y()*z()
中,*
的两个值计算可能以任意顺序进行
在您的代码中,&&
运算符有一个特殊的排序限制(有时称为短路)。在开始计算右操作数之前,必须先计算左操作数
优先级告诉我们&
的左操作数是fgg3()
,而&
的右操作数是fgg4()
。因此,要求在fgg4
、fgg5
和fgg6
之前调用fgg3()。在您的示例中,操作数的求值顺序没有其他限制。fgg2
可以在任何时候出现,4
、5
、6
可以是任何顺序,只要它们都在3
之后,您将优先级与求值顺序混淆了
这是一个相当普遍的困惑。也许是因为英语中的“prefere”这个词有时间含义。但实际上,它是指一种等级制度(例如)
在更简单的表达式a()+b()*c()
中,优先级告诉我们*
运算符的操作数是b()
和c()
,而+
的操作数是a()
和乘法的结果。不多也不少
函数a、b、c
仍然可以按任何顺序调用
确实,*
的值计算必须在+
的值计算之前进行,因为我们需要知道前者的结果才能计算后者
值计算是计算操作数的不同步骤。运算符的操作数必须在计算其值之前求值,但没有比这更严格的要求了。没有关于求值操作数偏序的规则
+
的左操作数的求值可能先于+
的右操作数,即使右操作数由许多子表达式组成。编译器可能会计算所有“叶”操作数,将结果存储在堆栈中,然后执行值计算
也不一定有严格的值计算顺序,例如在w()*x()+y()*z()
中,*
的两个值计算可能以任意顺序进行
在您的代码中,&&
运算符有一个特殊的排序限制(有时称为短路)。在开始计算右操作数之前,必须先计算左操作数
优先级告诉我们&
的左操作数是fgg3()
,而&
的右操作数是fgg4()
。因此,要求在fgg4
、fgg5
和fgg6
之前调用fgg3()。在您的示例中,操作数的求值顺序没有其他限制。fgg2
可以在任何时候发生,4
、5
、6
可以是任何顺序,只要它们都在3
之后,您忘了考虑和&
操作员的短路评估
&&
运算符的左侧总是在右侧之前求值
在您尝试简化操作时,r3
的前半部分必须是evalua
int r1 = fggg5() * fggg6(); //Precedence 3 (inside parens)
int r2 = fggg4() < r1; //Precedence 6 (inside parens)
int r3 = fggg3() && r2; //Precedence 11 (inside parens)
int ggg9 = fggg2() + r3; //Outside of parens, so it's last
int i0;
int r2 = fggg2();
int r3 = fggg3();
if(!r3) goto L13;
int r4 = fggg4();
int r5 = fggg5();
int r6 = fggg6();
int i1 = r5 * r6;
if(r4 >= i1) goto L13
i0 = 1;
goto L14
L13:
i0 = 0;
L14:
int ggg9 = i0 + r2;