C++ 函数参数和默认参数的求值顺序

C++ 函数参数和默认参数的求值顺序,c++,undefined-behavior,operator-precedence,default-parameters,C++,Undefined Behavior,Operator Precedence,Default Parameters,我最近遇到了以下情况: #include <iostream> int *p = 0; int f() { p = new int(10); return 0; } void g(int x, int *y = p) { std::cout << y << std::endl; } int main() { g(f()); } #包括 int*p=0; int f(){ p=新整数(10); 返回0; } 空g(整数x

我最近遇到了以下情况:

#include <iostream>

int *p = 0;

int f() {
    p = new int(10);
    return 0;
}

void g(int x, int *y = p) {
    std::cout << y << std::endl;
}

int main() {
    g(f());
}
#包括
int*p=0;
int f(){
p=新整数(10);
返回0;
}
空g(整数x,整数*y=p){
std::cout未指定函数参数的求值顺序(即确定值)。编译器可以任意顺序执行它们,如果没有其他因素阻止编译器执行,甚至可以混合执行


默认参数的计算是在调用方的上下文中进行的,而不是在被调用方的上下文中进行的。因此,对一个参数调用f()是必要的,而对另一个参数调用全局变量p是必要的。没有指定这种情况发生的顺序,因此可以在调用f()之前或之后读取全局变量。

如果我理解正确,您的调用

    g(f());
相当于

    g(f(), p);
由于申报

    void g(int x, int *y = p);

g
函数、
f()
p
的参数可以按任何顺序求值,因此可以调用
g
,并将
y
赋值为零(如果先求值
p
,然后返回其初始值)或新分配的数组指针(如果
f()
首先求值,它会将一个新值指定给
p
,作为其副作用)。

“默认参数的求值发生在调用方的上下文中”在当前的C++标准中,你有没有对这个说法的引用?在1.9p11中有一个非规范性的注释,它明确地说明了它。除此之外,我认为它仅仅是因为缺少与其他参数的区别而暗示的。@“每次调用函数时都会计算默认参数。函数参数的计算顺序是未指定的。”,我认为这显然意味着
g(f())
g(f(),p)