Exceptions pass information up the call stack to a point where error handling can be performed. If an object of class type is thrown, the class type itself serves to document the cause of an exception. Only types that inherit from std::exception, should be thrown.
TSP>Почему? Какая мотивация?
Я полагаю, идея в том что существует какой-то глобальный кэтч блок, ловящий именно std::exception. Лично я считаю данную рекомендацию необоснованной.
TSP>Exceptions pass information up the call stack to a point where error handling can be performed. If an object of class type is thrown, the class type itself serves to document the cause of an exception. Only types that inherit from std::exception, should be thrown.
TSP>Почему? Какая мотивация?
Это вопросы не по адресу, их надо задавать клангу.
От себя могу сказать следующее.
1) Любой проект, особенно крупный, идёт лучше, если в нём единообразно используется некоторая дисциплина программирования.
Даже если эта дисциплина не самая современная. В частности, такая дисциплина должна включать в себя паттерны обработки ошибок и исключительных ситуаций.
2) Необходимо различать ошибки и исключительные ситуации. Обработку исключительных ситуаций в современном C++ лучше всего делать, используя исключения,
а вот обработку ошибок можно реализовать по разному. Здесь надо принимать решения, основываясь на характере проекта.
3) При использовании исключительных ситуаций важно решить, а вам надо, на самом деле, передавать на верхний уровень какую-нибудь управляющую информацию или нет.
Если да, то лучше эту информацию закодировать, например в виде целочисленного кода ситуации и включить в объект исключения. Использовать разные типы исключений,
как это сделано в стандартной библиотеке, это плохая идея. Лучше делать так
catch(MyException ex) // только один catch
{
switch( ex.getCode() )
{
case ExCode::OutOfMemory : ....
case ExCode::LossOfPrecision : ....
case ExCode::CannotConnect : ....
}
}
Можно даже этот switch превратить в функцию (или несколько типичных функций) и использовать её (их) во всех catch блоках.
4) Так что идея наследовать всё от std::exception, по-моему, дурацкая.
Здравствуйте, TimurSPB, Вы писали:
TSP>Почему? Какая мотивация?
Предлагаю обратиться к C++ Core Guidelines, E.14. Основная рекомендация "Use purpose-designed user-defined types as exceptions (not built-in types)", что более чем разумно. Если подумать с той же точки зрения про std::exception — оно подходит еще лучше, так как позволяет организовать перехват всех исключений и какую-то базовую обработку, как минимум логирование сообщения перед дальнейшим пробросом, однообразно. В принципе, E.15: Catch exceptions from a hierarchy by reference, тоже дает понять зачем это нужно — если есть иерархия, то организовать обработку существенно проще.
Например, стандартный terminate handler умеет у потомка std::exception звать what() и получать строку — причину исключения.
Для всех остальных он покажет только тип исключения. Написал "throw 0" в одном месте, "throw 666" в другом, а он тебе только — "возбуждено int", без конкретного значения.
да, я все спрятал в exception filter и дублирования не было, но хорошо что мне не нужно было как то реагировать на исключительные ситуации а только логировать.
TSP>Exceptions pass information up the call stack to a point where error handling can be performed. If an object of class type is thrown, the class type itself serves to document the cause of an exception. Only types that inherit from std::exception, should be thrown.
TSP>Почему? Какая мотивация?
Если в исключении нужно сохранить текст, то часто это делают с помощью
std::string, что на самом деле не совсем правильно, так как работа с std::string может вызвать исключение.
Because copying std::runtime_error is not permitted to throw exceptions, this message is typically stored internally as a separately-allocated reference-counted string. This is also why there is no constructor taking std::string&&: it would have to copy the content anyway.
а в std::runtime_exception уже позаботились об этой проблеме.
try {
// Тут код
} catch std::exception { // Всякие OutOfMemory и LossOfPrecision должны выводиться из std::exception
process_current_exception()
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Vamp, Вы писали:
V>Я полагаю, идея в том что существует какой-то глобальный кэтч блок, ловящий именно std::exception.
Ну вообще-то странно его не иметь используя в коде хотя бы std::string и new
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Шахтер, Вы писали:
Ш>>
Ш>>catch(MyException ex) // только один catch
Ш>> {
Ш>> switch( ex.getCode() )
Ш>> {
Ш>> case ExCode::OutOfMemory : ....
Ш>> case ExCode::LossOfPrecision : ....
Ш>> case ExCode::CannotConnect : ....
Ш>> }
Ш>> }
Ш>>
Ш>>Можно даже этот switch превратить в функцию (или несколько типичных функций) и использовать её (их) во всех catch блоках.
E>Обычную стратегию обработки исключений разных типов тоже можно засунуть в функцию ничуть не хуже:
Я в курсе. Но это неэффективно, потому что через жопу.
Кстати, тут Саттер недавно речь толкал, как раз про исключения здесь.
Так вот, он там предлагает технически этот же подход, узаконенный в языке.
Здравствуйте, TimurSPB, Вы писали:
TSP>Почему? Какая мотивация?
У нас давно от исключений отказались. Слишком сложная логика. Лучше упасть с дампом, и дать его проанализировать (а это буквально занимает час времени программиста после утрешнего кофе), чем потом парится с кусками кода.
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
Здравствуйте, Мёртвый Даун, Вы писали:
МД>Здравствуйте, TimurSPB, Вы писали:
TSP>>Почему? Какая мотивация?
МД>У нас давно от исключений отказались. Слишком сложная логика.
В чём эта сложность выражается?
МД> Лучше упасть с дампом, и дать его проанализировать (а это буквально занимает час времени программиста после утрешнего кофе),
Что у вас за задачи, что анализировать дамп занимает час времени, а исключения дают непреодолимую сложность?
Здравствуйте, Шахтер, Вы писали:
Ш>>>Можно даже этот switch превратить в функцию (или несколько типичных функций) и использовать её (их) во всех catch блоках. E>>Обычную стратегию обработки исключений разных типов тоже можно засунуть в функцию ничуть не хуже: Ш>Я в курсе. Но это неэффективно, потому что через жопу.
Почему? Если по сути получится такой же switch, только по typeid?
Ш>Кстати, тут Саттер недавно речь толкал, как раз про исключения здесь. Ш>Так вот, он там предлагает технически этот же подход, узаконенный в языке.
У Саттера идея немного другая, КМК — он хочет уйти от аллокаций. Если передавать просто типом (что превращается в указатель на константную структуру) — их нет, если ограничить объём сопровождающей информации каким-то разумным значением и форсировать "плоскость" типа (чтобы можно всегда было копировать без проблем) — аналогично.
Здравствуйте, netch80, Вы писали:
Ш>>Я в курсе. Но это неэффективно, потому что через жопу. N>Почему? Если по сути получится такой же switch, только по typeid?
Цена нужного апкаста от типа, про который ты можешь даже не знать?
Ш>>Кстати, тут Саттер недавно речь толкал, как раз про исключения здесь. Ш>>Так вот, он там предлагает технически этот же подход, узаконенный в языке. N>У Саттера идея немного другая, КМК — он хочет уйти от аллокаций. Если передавать просто типом (что превращается в указатель на константную структуру) — их нет, если ограничить объём сопровождающей информации каким-то разумным значением и форсировать "плоскость" типа (чтобы можно всегда было копировать без проблем) — аналогично.
+1. Саттер фактически предлагает зафиксировать кидаемый тип в языке и кидать по значению.
Здравствуйте, Мёртвый Даун, Вы писали:
МД>У нас давно от исключений отказались. Слишком сложная логика. Лучше упасть с дампом, и дать его проанализировать (а это буквально занимает час времени программиста после утрешнего кофе), чем потом парится с кусками кода.