Порядок оценки аргументов функции и аргументов по умолчанию
недавно я столкнулся со следующей ситуацией:
#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());
}
Это довольно тонко, так как вы обычно не ожидаете, что аргументы по умолчанию изменятся во время их оценки для вызова функции. Я должен был взглянуть на сборку, чтобы обнаружить эту ошибку.
теперь мой вопрос: это действительно неопределенное поведение, так как нет никаких гарантий относительно порядка оценки аргументов функции?
2 ответов
порядок оценки (т. е. определения значения) аргументов функции не указан. Компилятор может выполнять их в любом порядке и даже смешивать, если нет других факторов, препятствующих этому.
оценка аргументов по умолчанию происходит в контексте вызывающего абонента, а не абонент. Таким образом, вызов f() необходим для одного аргумента, а чтение глобальной переменной p для другого. В каком порядке это происходит в не указывается, так может быть прочитан до или после вызова f ().
если я правильно понял, ваш звонок
g(f());
эквивалентно
g(f(), p);
из-за декларации
void g(int x, int *y = p);
и аргументы в пользу , f()
и p
, могут быть оценены в любом порядке, так что вы можете получить g
позвонил с y
назначено либо ноль (если p
сначала вычисляется, затем возвращается его начальное значение) или вновь выделенный указатель массива (если f()
сначала оценивается и присваивается новый значение p
как свой побочный эффект).