【问题标题】:C/C++ - evaluation of the arguments in a function call [duplicate]C / C ++ - 函数调用中参数的评估[重复]
【发布时间】:2012-02-02 16:32:29
【问题描述】:

可能重复:
order of evaluation of function parameters

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

f(g(), h());

g() 预计会被首先评估,然后是h()

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

【问题讨论】:

  • 这个问题在这里经常被问到,我无法决定选择哪一个作为重复标记...
  • 谢谢,但是真实世界的编译器呢?他们使用什么顺序?
  • @psihodelia:我看过每一个要使用的订单。

标签: c++ c semantics multiplatform


【解决方案1】:

不!无法保证这些执行的顺序。只有 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_list.See this question 的构造函数的调用。

【讨论】:

    【解决方案2】:

    参见 1.9 程序执行:

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

    和 8.3.6 默认参数,9:

    [...] 每次调用函数时都会评估默认参数。函数求值顺序 参数未指定。因此,函数的参数不应在默认参数中使用, 即使他们没有被评估。 [...]

    【讨论】:

      【解决方案3】:

      不,这不安全 - 如果您需要有保证的评估顺序,例如由于副作用,那么您将需要执行以下操作:

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

      【讨论】:

        【解决方案4】:

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

        【解决方案5】:

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

        【讨论】:

        • 取决于优化标志(和目标硬件)。
        猜你喜欢
        • 2020-02-15
        • 2016-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-21
        • 1970-01-01
        相关资源
        最近更新 更多