函数参数和默认参数的评估顺序

Evaluation order of function arguments and default arguments

我最近运行遇到以下情况:

#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());
}

这很微妙,因为您通常不希望默认参数在函数调用评估期间发生变化。我必须查看程序集才能发现此错误。

现在我的问题是:这真的是未定义的行为吗,因为没有关于函数参数求值顺序的任何 gua运行tees?

未指定函数参数的求值顺序(即确定值)。编译器可以按任何顺序自由执行它们,如果没有其他因素阻止它这样做,甚至可以混合使用。

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

如果我没理解错的话,你来电

    g(f());

相当于

    g(f(), p);

由于声明

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

g 函数 f()p 的参数可以按任何顺序求值,因此您可以用 [=17= 调用 g ] 分配零(如果首先评估 p,则它 returns 其初始值)或新分配的数组指针(如果首先评估 f() 并将新值分配给 p作为它的副作用)。