исключение — о безопасном использовании catch (…) в переполнении стека

Я спорил с коллегой об опасности использования catch(...)

Он указывал мне на возможное использование, строго подразумевая что нибудь catch(...) сопровождается следом / журналом: чтобы помочь определить происхождение некоторых неуправляемых исключений.

Я лично скептически отношусь к этому. Знаете ли вы о каком-либо явном безопасном использовании catch(...)

РЕДАКТИРОВАТЬ: Для тех, кто интересуется дебатами, мой коллега только что указал мне на этот вопрос на сайте программистов.

-2

Решение

Исключения часто злоупотребляют. Почти всегда это чрезмерное использование сопровождается всеобъемлющими утверждениями. Обычно это признак плохого использования и понимания исключений. Я никогда не рекомендую это. К сожалению, в каком-то (плохом) месте, где я работал, другие люди применяли эту политику.

4

Другие решения

Ярчайшее интересное безопасное использование catch(...) я знаю о том, чтобы разгрузить код для обработки различных исключений для совместно используемой функции:

void handle_error() {
try {
throw;
} catch (TiresomelyPedanticException &) {
# lah lah I don't care
return;
} catch (InterestingException &) {
log_something();
throw;
}
// etc. This catch chain may *or may not* need a catch(...)
// of its own, it depends whether part of its job is to
// deal with the "miscellaneous" case.
}

Вы используете функцию как это:

try {
blah();
} catch(...) {
handle_error();
}

… где-нибудь еще …

try {
something_that_throws_the_same_exceptions_as_blah();
} catch (...) {
handle_error();
}

Однако приведенный выше шаблон может показаться чем-то вроде C ++ 03. В C ++ 11 написать лямбду захвата так легко, что следующее может быть более полезным для вызывающих, и нет catch(...) в шаблоне:

template <typename Func>
auto do_and_handle_error(Func f) -> decltype(f()) {
try {
return f();
} // catch chain goes here
}

Используйте это как:

do_and_handle_error(blah);

или, как на самом деле окажется необходимым, когда blah принимает аргументы:

do_and_handle_error([&](void) { return blah(arg1,arg2); });

Скучное использование catch(...) является гарантией того, что стек будет размотан до завершения программы:

int my_main() {
RAIIClass some_object_i_want_to_get_destroyed_no_matter_what;
some_code_that_might_throw();
return 0;
}

int main() {
try {
return my_main();
} catch (...) {
throw;
}
}

Без улова стандарт оставляет его либо неопределенным, либо определяемым реализацией, независимо от того, some_object уничтожается, если выдает код.

5

Следующее всегда безопасно:

try
{
some_local_stuff();
}
catch (...)
{
clean_up_local_stuff();
throw;
}

Другими словами, всеобъемлющее catch Блок должен использоваться только в сочетании с перебрасыванием того же самого исключения или сохранением указателя исключения для транспортировки исключения.

Блоки Catch, которые полностью исключают исключение, должны конкретно указывать тип исключения, которое они обрабатывают.

3
По вопросам рекламы [email protected]