Если я выпрыгну из блока catch с помощью «goto», я гарантирую, что объект исключения будет освобожден? - PullRequest
13 голосов
/ 01 сентября 2011

У меня есть такой код следующим образом

try {
  doSomething();
} catch(InterruptException) {
  goto rewind_code;
}

if(0) {
rewind_code:
  longjmp(savepoint, 1);
}

Мой вопрос такой: свободен ли объект исключения, который сохраняется во время выполнения C ++, когда я goto выходит из блока catch?Или среде выполнения разрешено кэшировать ее до тех пор, пока не появится окружающая функция или что-то в этом роде?Я просто хочу убедиться, что если я выполню приведенный выше код несколько раз, каждый раз, принимая код перемотки, я не утечу память (потому что longjmp не будет выполнять код очистки, испускаемый компилятором в прологах функций или перед ними).

Ответы [ 2 ]

11 голосов
/ 01 сентября 2011

§6.6 / 2:

При выходе из области (хотя и выполненной) деструкторы (12.4) вызываются для всех построенных объектов с автоматической продолжительностью хранения ...

По крайней мере, как я прочитал, "как бы это ни было" должно включать / действительно включает goto.

Редактировать: Хорошо, основываясь на комментарии Йоханнеса, нас интересует §15.1 / 4:

Когда последний обработчик для исключения завершается любым способом, кроме throw;временный объект уничтожается, и реализация может освободить память для временного объекта;

[...]

Уничтожение происходит сразу после уничтожения объекта, объявленного в объявлении исключения в обработчике.

4 голосов
/ 01 сентября 2011

§ 15.1.4

Память для объекта исключения выделяется неопределенным образом, за исключением случаев, отмеченных в 3.7.4.1.Если обработчик завершается повторным сбросом, управление передается другому обработчику для того же исключения. Объект исключения уничтожается после того, как последний оставшийся активный обработчик для исключения исключается любыми средствами, кроме повторного выброса , или последнего объекта типа std :: exception_ptr (18.8.5), который ссылается на объект исключенияуничтожен, в зависимости от того, что позже.В первом случае уничтожение происходит при выходе из обработчика, сразу после уничтожения объекта, объявленного в объявлении исключения в обработчике, если оно есть. Во втором случае уничтожение происходит до деструктораиз std :: exception_ptr возвращает.Реализация может затем освободить память для объекта исключения;любое такое освобождение осуществляется неуказанным способом.

...