7

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

#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)充当序列点?

4

2 回答 2

9

不,它不会调用未定义的行为。它只是unspecified,因为标准中未指定评估函数参数的顺序。因此输出可能是042取决于编译器决定的评估顺序。

于 2013-08-29T16:40:42.137 回答
4

程序的行为是未指定的,因为我们不知道函数参数的评估顺序,来自草案 C++ 标准 1.9 程序执行第 3 段

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

并且参数的所有副作用都在输入函数之前排序,来自5.2.2 函数调用第 8 段

[注意:后缀表达式和参数表达式的计算相对于彼此都是无序的。参数表达式求值的所有副作用都在输入函数之前排序(见 1.9)。——尾注]

至于这两点, C99 草案标准中的功能调用第 10 段C中涵盖了这两个点:6.5.2.2

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

因此,在两者中CC++您都可以以f(0,0)or结束f(42,0)

于 2013-08-29T16:50:17.673 回答