下面的输出应该是什么以及为什么它应该依赖于编译器?

时间:2017-12-25 15:47:23

标签: c

请帮助我理解输出。我们知道,我们不能说f1()是在f2()之前评估的,因为左右关联性是' +'因为关联性只发生在有2个或2个以上相同优先级的运算符时。那么用于确定答案的概念应该是什么?

// Associativity is not used in the below program.
int x = 0; 
int f1() {
  x = 5;
  return x;
} 
int f2() {
  x = 10;
  return x;
}
int main() {
  int p = f1() + f2();
  printf("%d ", x);
  return 0;
}

2 个答案:

答案 0 :(得分:3)

因为标准没有对其施加任何约束。

说明这一点的部分来自6.5

  

运算符和操作数的分组由语法表示.85)   除非后面指定,否则副作用和值计算   子表达式没有排序。

从标准本身6.5.2.2(显示标准不强加任何约束的示例)

  

在函数调用中

  (*pf[f1()]) (f2(), f3() + f4())
  

可以按任何顺序调用函数f1f2f3f4 。各方面   效果必须在函数指向之前完成   pf[f1()]被称为。{/ p>

您的问题的答案将是未指定。你不能肯定地说些什么。如果调用f1(),那么第一个结果将是某种东西,如果它是相反的,那么结果就会不同。

为支持我所说的内容,请检查此link

  

...在表达式f(i++) + g(j++) + h(k++)中,使用a调用f   i原始值的参数,但i之前递增   进入f的身体。同样,jk之前会更新   分别输入gh但是,未指定   执行f(),g(),h()的顺序,也不执行i,j,k的顺序   递增。如果f的主体访问变量j和k,则它   可能会发现两者,既不是,也不只是其中之一   递增。 (函数调用f(a,b,c)不是逗号的用法   操作; a,b和c的评估顺序未指定。)

答案 1 :(得分:3)

这两个函数调用是不确定地排序w.r.t.彼此C11 6.5.2.2p10

  

在评估函数指示符和实际参数之后但在实际调用之前有一个序列点。 调用函数中的每个评估(包括其他函数调用)在执行被调用函数体之前或之后没有特别排序,对于执行该函数的执行情况是不确定的。叫做函数。

不确定地排序意味着C11 5.1.2.3p3

  

当A在B之前或之后进行测序时,评估A和B是不确定的测序,但未指明哪个

因此,首先调用f1f2,并且不会交错执行函数。您可以通过检查x的值来告诉它 - 如果它是5,则先调用f2;如果10,则先调用f1

footnote 86也说:

  

在程序执行期间多次评估的表达式中,不需要在不同的评估中一致地执行对其子表达式的未测序和不确定顺序的评估。

即。如果您在循环中执行此操作,则可能首先调用f1,然后可能首先调用下一个f2 ...

运算符关联性和优先级与评估的实际顺序几乎没有任何关系< - +的操作数的评估顺序与几乎所有其他运算符一样,是{{ 3}}