Подтвердить что ты не робот

С++ деструктор и вызов вызова функции

Предположим, что у меня есть следующий сниппл:

Foo foo;
....
return bar();

Теперь, подтверждает ли стандарт С++, что bar() будет вызываться до foo:: ~ Foo()? Или это выбор компилятора/реализации?

Спасибо!

4b9b3361

Ответ 1

Это гарантированное поведение. Фактическое выполнение разворачивается следующим образом:

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 Локальные объекты, явно объявленные автоматически или зарегистрированные или явно не объявленные статические или внешние имеют время автоматического хранения. Хранение для эти объекты сохраняются до тех пор, пока не завершится создание блока, в котором они созданы.

  • Что такое фактический эффект оператора return

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)

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

Ответ 2

Да, bar() вызывается перед деструктором foo.

В стандарте говорится: 6.6: "При выходе из области действия (однако, достигнутой) деструкторы (12.4) для всех построенных объектов с автоматической продолжительностью хранения (3.7.2) (именованные объекты или временные), объявленные в этой области, в обратном порядке их объявления. "

Сфера не остается до завершения оператора return.

Ответ 3

Результат вызова bar() должен быть оценен до того, как фрейм стека, содержащий Foo, может быть очищен, так что да, bar() вызывается перед Foo:: ~ Foo().

Ответ 4

Объекты уничтожают при выходе из области.

return выходит из области видимости, но не может вернуться, пока не выполнит bar(). Ergo, bar().

Ответ 5

Просто подумайте, что, если это было return bar(foo);? Это просто должно работать, и было бы глупо, если бы порядок уничтожения был другим в зависимости от того, передаете ли вы это в качестве аргумента или нет.