这是另一个序列问题,但是一个相当简单的问题:
#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)
的调用是否作为序列点?
答案 0 :(得分:9)
没有。它不会调用 undefined 行为。它只是未指定,因为在标准中未指定评估函数参数的顺序。因此,输出可以是0
或42
,具体取决于编译器决定的评估顺序。
答案 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}}。