这就是我今天编码的内容
#include <iostream>
using namespace std;
int function1()
{
cout<<"hello from function1()"; return 0;
}
int function2()
{
cout<<"hello from function2()"; return 0;
}
int main()
{
int func_diffresult = 0;
func_diffresult = function1() - function2();
cout<<func_diffresult; /** prints 0 correctly **/
}
输出为hello from function2()hello from function1()
。我认为输出应该是hello from function1()hello from function2()
。我的编译器和我一起玩吗?
答案 0 :(得分:10)
-
运算符的参数评估顺序为unspecified。因此可以按任何顺序调用函数。
答案 1 :(得分:5)
-
运算符实际上变为operator-(function1(), function2())
,并且故意未指定函数参数的评估顺序。
相关说明:
保留未指定的一个很好的理由是有效地处理调用约定。例如,C调用约定要求以 reverse 顺序将参数压入堆栈。
因此,以相反的顺序评估函数是有意义的,因为可以立即推送结果。要从左到右评估参数,然后从右到左推送结果,请在推送任何结果之前存储所有结果。如果您确实需要这样做,可以手动完成。如果对您没有关系,那么性能优势可能会有所帮助。
答案 2 :(得分:2)
ISO标准不保证评估子表达式的顺序。
来自c ++ 0x草案标准:
<强> 1.9。程序执行:
的 强>
13 / 之前排序的是由单个线程执行的评估之间的不对称,传递,成对关系,这导致这些评估之间的部分顺序。给定任何两个评估A和B,如果A在B之前被排序,那么A的执行应该在B的执行之前。如果A在B之前没有排序,而B在A之前没有排序,那么A和B是未排序的。 [注:执行无序
评估可以重叠。]
当在A之前对B进行测序或在A之前对B进行测序时,评估A和B是不确定的,但未指定哪一个。 [注意:不确定顺序的评估不能重叠,但可以先执行。]
的 强>
15 / 除非另有说明,否则对各个操作员的操作数和单个表达式的子表达式的评估都是无效的。
的 强>
当调用函数(函数是否为内联函数)时,与任何参数表达式相关联的每个值计算和副作用,或者使用指定被调用函数的后缀表达式,都会在执行每个表达式或语句之前对其进行排序。被称为函数 [脚注:换句话说,函数执行不相互交错] 。 [注意:与不同参数表达式相关的值计算和副作用未被排序。]
调用函数(包括其他函数调用)中的每个评估(在执行被调用函数体之前或之后没有特别排序)对被调用函数的执行进行不确定的排序。
换句话说,实现可以使用它想要的任何方法自由安排调用。但是,根据脚注特别处理函数调用 - 它们不交错。