呼叫顺序和副作用

Order of calls and side effects

本文关键字:副作用 顺序 呼叫      更新时间:2023-10-16

考虑如下操作:

int a = f1(mystream)*f2(mystream)+f3(mystream);

其中f1, f2, f3的形式如下:

int f(std::istream&)

int f(std::ostream&)

我能保证f1, f2f3会按照这个顺序执行吗?

No。各个子表达式彼此之间没有排序。可以保证的是,任何一个函数调用都在另一个函数开始之前完成,但是三个函数调用的顺序是不确定的。

您不能保证每个编译器都使用左-右顺序。因此,如果您不确定,您可以在汇编代码中查找它。一旦编译器创建了汇编代码,顺序就得到了保证。看看下面的汇编代码:

cout << f1() * f2() * f3();
00C6452E  call        f1 (0C61096h)  
00C64533  mov         esi,eax  
00C64535  call        f2 (0C6112Ch)  
00C6453A  imul        esi,eax  
00C6453D  call        f3 (0C61127h) 
00C64542  imul        esi,eax  
00C64545  mov         edi,esp 

不,它们可以按任何顺序执行。这是因为内置的*+操作符没有引入序列点。有些内置操作符,如||&&,确实引入了序列点,并定义了执行的顺序。