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

时间:2012-04-27 22:30:19

标签: c

在以下代码中:

int foo();
int bar();
int i;

i = foo() + bar();

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

5 个答案:

答案 0 :(得分:12)

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

  

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

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

答案 1 :(得分:7)

未指明,在C99的情况下,相关报价为6.5 / 3:

  

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

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

函数调用的“稍后”与此处没有直接关系,但作为参考,它是6.5.2.2/10:

  

功能指示符的评估顺序,实际   参数和实际参数中的子表达式是   未指定,但在实际呼叫之前有一个序列点。

对于&&,它是6.5.13 / 4:

  

与按位二进制&操作员,&&运营商保证   从左到右的评价;之后有一个序列点   评估第一个操作数。

由于+不在顶部的运算符列表中,&&+&&和{{1}的方式相同“不同” “不像”,这正是你要问的问题。与&不同,&& 保证从左到右的评估。

答案 2 :(得分:2)

不,它不是。函数和运算符参数的评估顺序是未定义的。

标准只说,foobar的调用不能交错,这在评估没有函数调用的子表达式时会发生。

答案 3 :(得分:0)

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

  

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

K& R描述了加法运算符,并没有定义两个运算数的赋值器的顺序。

答案 4 :(得分:0)

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