Есть ли этот код
try
{
opaque_function_that_might_throw_arbitrary_exception ();
}
catch (...)
{
throw;
}
семантически отличаются от простого вызова
opaque_function_that_might_throw_arbitrary_exception ();
в С ++? Есть ли различия между стандартами?
Хотя оба фрагмента были семантически идентичны, я проверил с помощью компилятора-проводника, и он генерирует другой код даже на самом высоком уровне оптимизации. Это заставило меня задуматься, если я что-то упускаю.
Да, есть небольшая разница в одном конкретном месте. Рассмотрим эту основную функцию:
int main() {
RAIIHandle important_resource{ /*...*/ };
opaque_function_that_might_throw_arbitrary_exception ();
}
Является important_resource
освобожден после исключения? Ну, это реализация определена. std::terminate
вызывается, но стек не может быть размотан, если исключение выходит из main
, Для некоторых ресурсов это может означать реальные проблемы.
Теперь в этом случае:
int main() {
try {
RAIIHandle important_resource{ /*...*/ };
opaque_function_that_might_throw_arbitrary_exception ();
}
catch(...) {
throw;
}
}
std::terminate
все еще называется. Но не раньше, чем найдется подходящий обработчик для исключения. Стек должен быть размотан. Так что наши important_resource
определенно освобожден.
Других решений пока нет …