C 操作顺序 -- foo() + bar() -- 必须在 bar 之前调用 foo

  • 本文关键字:bar foo 调用 操作 顺序 c
  • 更新时间 :
  • 英文 :


在下面的代码中:

int foo();
int bar();
int i;
i = foo() + bar();

C 标准是否保证在调用之前调用foo bar

不,没有+的序列点。维基百科页面上实际上有一段关于它的引用可以回答您的问题:

考虑两个函数 f(( 和 g((。在 C 和 C++ 中,+ 运算符不与序列点相关联,因此在表达式 f((+g(( 中,可能会首先执行 f(( 或 g((。

http://en.wikipedia.org/wiki/Sequence_points

它没有指定,在 C99 的情况下,相关报价为 6.5/3:

除非稍后指定(对于函数调用()&&||?: 和 逗号运算符(,子表达式的求值顺序和 副作用发生的顺序均未指定。

在您的示例中,foo()bar() 是完整表达式 i = foo() + bar() 的子表达式。

函数调用的"later"在这里没有直接关系,但作为参考,它是 6.5.2.2/10:

函数指示符的求值顺序,实际 参数和实际参数中的子表达式是 未指定,但在实际调用之前有一个序列点。

对于&&,它是 6.5.13/4:

与按位二进制和运算符不同,&&&运算符保证 从左到右的评估;后面有一个序列点 第一个操作数的评估。

由于+不在顶部的运算符列表中,因此&&+"不像",就像&&&"不像"一样,这正是您要问的事情。与&&不同,+不能保证从左到右的评估。

不,不是。函数和运算符参数的求值顺序未定义。

该标准仅规定,对foobar的调用不能交错,这在计算没有函数调用的子表达式时可能会发生。

不,这没有定义。 来自K&R第200页:

除某些例外情况外,表达式的计算顺序是未定义的,即使子表达式涉及副作用也是如此。 也就是说,除非运算符的定义保证其操作数按特定顺序计算,否则实现可以自由地以任何顺序计算操作数,甚至可以交错计算它们的计算。

K&R的第205页描述了加法运算符,并没有定义两个操作数的求值顺序。

我工作的正确答案是"如果顺序很重要,那么无论标准说会发生什么,代码都是不可维护的"。如果必须在 bar(( 之前计算 foo((,请在 bar(( 之前显式计算 foo((。这样做的基础不是每个程序员都知道标准,而那些知道标准的人不知道原作者是否知道。

最新更新