Какой аргумент по умолчанию оценивается первым и почему?

У меня есть три функции: funt1(), funt2() и funt3().

int funt1()
{
    cout<<"funt1 called"<<endl;
    return 10;
}

int funt2()
{
    cout<<"funt2 called"<<endl;
    return 20;
}

void funt3(int x=funt1(), int y=funt2())
{
    cout << x << y << endl;
}

Моя функция main:

int main()
{
    funt3();
    return 0;
}

Когда я вызываю funt3() в моем методе main(), почему сначала вызывается funt1(), а затем funt2()?

Ответ 1

Стандарт С++ не определяет это, поэтому он полностью зависит от компилятора. Тем не менее, вы никогда не должны полагаться на экземпляр поведения undefined.

EDIT: если вы действительно хотите сохранить функции invocations в качестве параметров по умолчанию, чтобы уменьшить количество параметров, которые вы должны передавать каждый раз, я предлагаю вам сделать следующее:

void funt3(int x, int y)
{
    cout<<x<<y<<endl;
}

void funt3(int x)
{
    funt3(x, funt2());
}

void funt3()
{
    funt3(funt1());
}

Ответ 3

Язык не требует особого порядка. Используемый порядок будет зависимым от компилятора.

Ответ 4

Это потому, что параметры funt3 (sp?) должны работать x, а затем y. т.е. funt1(), затем funt2(), прежде чем рассматривать содержимое funt3.

Ответ 5

Спецификатор компилятора, и оттуда он переходит в CPU. CPU может разветкить этот вызов на отдельные ветки, он может попытаться сделать некоторые прогнозы или если процессор считает, что func1 быстрее, чем func2, он будет запускать func1 и множество других операций перед func2, чтобы он оптимизировал.

Ответ 6

Поскольку стандарт С++ не определяет порядок, поэтому он зависит от компилятора.

Вы можете просто попробовать несколько популярных компиляторов С++: GCC, VS2008/VS2010 и т.д. Тогда вы увидите совершенно другой результат.

Ответ 7

зависит от компилятора. это может быть funt1, затем funt2, затем funt3 или любая другая комбинация.

Ответ 8

Как отмечают все остальные, порядок оценки параметров функции не определен стандартом С++. Это позволяет каждому компилятору выбирать оптимальный порядок, независимо от того, определяется ли этот порядок по удобству или эффективности.

Вы даже можете обнаружить, что заказ может измениться на основе флагов оптимизации, которые вы даете своему компилятору.

Чтобы гарантировать последовательность вызовов функций, вам необходимо ввести последовательность точек между вызовами. Я выполняю это ниже, создавая две разные версии функции, так что в качестве параметра делается только один вызов функции.

void funt3(int x, int y=funt2())
{
    cout << x << y << endl;
}

void funt3()
{
    int x = funt1();
    funt3(x);
}