C / C ++ - 评估函数调用中的参数

时间:2012-02-02 16:32:30

标签: c++ c semantics multiplatform

  

可能重复:
  order of evaluation of function parameters

在C / C ++中使用以下结构是否安全?

f(g(), h());

预计g()将被评估为第一个,然后是h()

所有编译器是否在所有架构上都显示相同的行为?

5 个答案:

答案 0 :(得分:8)

NO!无法保证这些命令的执行顺序。只有g()和h()都在f()之前执行。 见:http://www.gotw.ca/gotw/056.htm 我认为有一个更新的C ++ 11版本,我来看看。

编辑:C ++ 11版http://herbsutter.com/gotw/_102/

编辑2:如果你真的想知道具体的编译器是做什么的,试试这个:http://www.agner.org/optimize/calling_conventions.pdf 第7节(第16页)可能是相关的,虽然它有点过头,但是例如__cdecl调用约定意味着参数从右向左传递(至少以那种方式存储),而对于__fastcall“前两个DWORD或更小参数在ECX和EDX寄存器中传递;所有其他参数从右到左传递。“ (http://msdn.microsoft.com/en-us/library/6xa169sk%28v=vs.71%29.aspx

因此对于不同的编译器而言确实有所不同。

很多以后编辑:事实证明,对于使用初始化列表语法(花括号{})的构造函数,的评估顺序是保证(即使它是对构造函数的调用,不会使用std::initializer_listSee this question

答案 1 :(得分:1)

参见1.9程序执行:

  

抽象机的某些其他方面和操作在本国际标准中描述为   未指定(,例如,函数参数的评估顺序)。如果可能,这个国际   标准定义了一组允许的行为。

和8.3.6默认参数,9:

  

[...]每次调用函数时都会计算默认参数。功能评估的顺序   参数未指定。因此,函数的参数不得用于默认参数,   即使他们没有被评估。 [...]

答案 2 :(得分:1)

不,这不安全 - 如果您需要有保证的评估订单,例如因为副作用,那么你需要做这样的事情:

foo = g();
bar = h();
f(foo, bar);

答案 3 :(得分:0)

不,参数的评估顺序是未指定的。您唯一的保证是它们不会彼此同时执行。

答案 4 :(得分:0)

没有。 在这种情况下,标准不定义评估顺序,每个编译器可以做任何想做的事情。 我认为他们中的大多数人(特别是gcc)首先评估最优秀的人。