函数调用序列 (C++)

Sequence of function calls (C++)

本文关键字:C++ 函数调用      更新时间:2023-10-16
result= function_1()*function_2();

我正在编写像上面这样的代码。我想知道的是,在做乘法时,哪个函数先调用?这是因为,第一个调用的函数可以影响从另一个函数返回的结果。我假设function_1()是首先调用的,当我尝试时,我发现确实如此。但是,情况总是如此吗?这是否取决于我使用的编译器或我使用的系统?

评估顺序未由C++(或 C(标准指定(参见 Vlad 的答案(。如果你的function_1function_2有明显的副作用,它可能会变成一些你应该绝对避免的未指定的行为(比如你应该避免未定义的行为(。在某些情况下(具有强大优化的内联函数(,计算可能会混合在一起。

想想奇怪的案例,比如

 static int i;
 int function_1(void) { i++; return i; }
 int function_2(void) { i+=2; return 3*i+1; }

它可能是特定于实现的,并且可能取决于实际的编译器和优化标志。

您应该编写代码,就好像函数调用的顺序是完全随机且不可重现的(即使在实践中它可能是可重现的(。同样,您不应该期望参数计算的任何特定顺序(例如,f(i++, ++j)您不知道ij是否首先递增(,即使对于给定的编译器,该顺序可能是固定的。同样,您应该想象一个完全随机且不可重现的顺序。

正如David Schwartz所评论的那样,如果你关心顺序,你应该明确地编写一些序列点。

最后,如果你的代码依赖于某种顺序,它是完全不可读的,出于简单的可读性原因,你应该避免以这种方式编码。

根据

C++标准(1.9程序执行(

15 除另有说明外,对个别经营者操作数的评价 和单个表达式的子表达式是未排序的。

所以在这个表达中

result= function_1()*function_2();

一些编译器可以先计算 function_1(( 然后是 function_2((,而其他编译器可以先计算 function_2((,然后再计算 function_1((。即使你写得像

result= (function_1())*(function_2());

result= (function_1())*function_2();

result= function_1()*(function_2());

相对于操作数的计算顺序,不会有任何更改。