函数调用的序列点?

时间:2013-08-29 16:38:53

标签: c++ c undefined-behavior sequence-points

这是另一个序列问题,但是一个相当简单的问题:

#include <stdio.h>
void f(int p, int) {
  printf("p: %d\n", p);
}

int g(int* p) {
  *p = 42;
  return 0;
}

int main() {
  int p = 0;
  f(p, g(&p));
  return 0;
}

这是未定义的行为吗?或者对g(&p)的调用是否作为序列点?

2 个答案:

答案 0 :(得分:9)

没有。它不会调用 undefined 行为。它只是未指定,因为在标准中未指定评估函数参数的顺序。因此,输出可以是042,具体取决于编译器决定的评估顺序。

答案 1 :(得分:4)

程序的行为未指定,因为我们不知道函数参数的评估顺序,来自draft C++ standard 1.9 程序执行第3段:< / p>

  

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

并且在输入函数之前对参数的所有副作用进行排序,从5.2.2 部分调用函数调用第8段

  

[注意:后缀表达式和参数表达式的评估都是相对于彼此的未经测序的。 在输入函数之前对参数表达式评估的所有副作用进行排序(参见1.9)。 - 后注]

至于C 6.5.2.2部分C 函数调用第10段中涵盖了这两点:

  

函数指示符的评估顺序,实际参数和   实际参数中的子表达式未指定,但有一个序列点   在实际通话之前。

因此,在C++f(0,0)中,您最终都可以使用f(42,0)或{{1}}。