Предположим, что у меня есть следующий сниппл:
Foo foo;
....
return bar();
Теперь, подтверждает ли стандарт С++, что bar() будет вызываться до foo:: ~ Foo()? Или это выбор компилятора/реализации?
Спасибо!
Предположим, что у меня есть следующий сниппл:
Foo foo;
....
return bar();
Теперь, подтверждает ли стандарт С++, что bar() будет вызываться до foo:: ~ Foo()? Или это выбор компилятора/реализации?
Спасибо!
Это гарантированное поведение. Фактическое выполнение разворачивается следующим образом:
0: enter block (scope)
1: Foo::Foo()
2. evaluation of bar(); as expression in return statement
3. save result of the expression as value returned from function
4. finalize return statement to leave function to its caller (request exit from current scope)
5: exit block (scope) with call to Foo::~Foo()
Вот некоторые ссылки из стандарта:
1.9 Выполнение программы
10 Экземпляр каждого объекта с автоматической продолжительностью хранения (3.7.2) связанных с каждой блок.
foo
имеет продолжительность автоматического хранения и:3.7.2 Автоматическая продолжительность хранения
1 Локальные объекты, явно объявленные автоматически или зарегистрированные или явно не объявленные статические или внешние имеют время автоматического хранения. Хранение для эти объекты сохраняются до тех пор, пока не завершится создание блока, в котором они созданы.
6.6.3 Оператор return
2 (...) значение выражения возвращается вызывающей функции
и
6.6 Операторы перехода (возврат относится к операторам перехода)
2 При выходе из области действия (как бы это ни было выполнено) деструкторы (12.4) вызываются для всех построенные объекты с автоматическим временем хранения (3.7.2)
6.7 Заявление о декларации
2 Переменные с автоматическим временем хранения, объявленным в блоке, являются уничтожен при выходе из блока
и
12.4 Деструкторы
10 Деструкторы вызываются неявно (1) для построенного объект со статической продолжительностью хранения (3.7.1) при завершении программы (3.6.3), (2) для построенного объекта с автоматической продолжительностью хранения (3.7.2), когда блок, в котором объекту созданы выходы (6.7)
Нелегко понять детали единой идеи, разбросанные по всему стандарту С++. Надеюсь, быстрый обзор поможет вам сделать такой анализ самостоятельно.
Да, bar() вызывается перед деструктором foo.
В стандарте говорится: 6.6: "При выходе из области действия (однако, достигнутой) деструкторы (12.4) для всех построенных объектов с автоматической продолжительностью хранения (3.7.2) (именованные объекты или временные), объявленные в этой области, в обратном порядке их объявления. "
Сфера не остается до завершения оператора return.
Результат вызова bar() должен быть оценен до того, как фрейм стека, содержащий Foo, может быть очищен, так что да, bar() вызывается перед Foo:: ~ Foo().
Объекты уничтожают при выходе из области.
return
выходит из области видимости, но не может вернуться, пока не выполнит bar()
. Ergo, bar()
.
Просто подумайте, что, если это было return bar(foo);
? Это просто должно работать, и было бы глупо, если бы порядок уничтожения был другим в зависимости от того, передаете ли вы это в качестве аргумента или нет.