Название: Как пользоваться исключениями Отправлено: __Heaven__ от Июнь 15, 2015, 20:07 Привет, друзья!
Я никогда не пользовался исключениями, но хотел бы научиться. Как они работают и синтаксис я понял. Не ясно вот что: Что принято бросать в какой ситуации? Допустим, у меня нет указанного файла, что бросать? Есть ли смысл наследоваться от стандартных классов, QException. Нужно ли придумывать и указывать код ошибки? Оно нужное дело вообще или можно статусами обойтись? Название: Re: Как пользоваться исключениями Отправлено: Авварон от Июнь 15, 2015, 20:20 Не используйте исключения в кутешном коде.
Название: Re: Как пользоваться исключениями Отправлено: Igors от Июнь 16, 2015, 09:27 Оно нужное дело вообще или можно статусами обойтись? Однозначно нужное, хотя бы потому что это штатное средство языка. А вот насколько - есть разные мнения. Я стараюсь всегда обойтись кодом ошибки до тех пор пока необходимость исключений не станет очевидной. Другие наоборот, используют исключения при первой возможности.Что принято бросать в какой ситуации? Допустим, у меня нет указанного файла, что бросать? Да на все вопросы. Опять-таки насколько нужно размазывать классы исключений - дело вкуса/стиля. ПримерЕсть ли смысл наследоваться от стандартных классов, QException. Нужно ли придумывать и указывать код ошибки? Код Испускающий не знает имени файла при чтении которого произошла ошибка - зато прекрасно знает что случилось Код Ловящий наоборот, имя файла знает, но что конкретно случилось - нет. Вот и комбинируйте Название: Re: Как пользоваться исключениями Отправлено: Akon от Июнь 19, 2015, 15:30 Я широко использую исключения в Qt-приложениях. Ho! Нужно понимать как будет проходить исключение через код Qt, и что этот код делает при наличии исключения. Во многих случаях код Qt просто не рассчитан на возможное наличие исключения, и вы можете получить утечку памяти, крах, или неопределенное поведение.
Одни участки Qt-кода могут быть адаптированы (перекрытие виртуальных методов) вами для корректной работы с исключениями, например, если вы выбросите исключение из QAbstractItemModel::setData(), то у вас завалится любой делегат из Qt, но вы можете сделать свой класс делегата с соответствующей функцией. Другие - могут быть относительно легко адаптированы с помощью патчинга сорцов Qt с последующей перекомпиляцией, например, я делал патчинг QObject::activate() с целью выбрасывать исключения из слотов с дефолтным показом сообщения и без разрыва вызова цепочки слотов. С третьими - по большому счету никак. В основном, исключения больше пронизывают ваш код, чем Qt. Наследовать исключения лучше от std::exception, все ошибки времени выполнения - от std::runtime_error. При использовании исключений вместа кода ошибки (категории кода ошибки) используется тип исключения. Все std-исключения минимально функциональны (хотя их функций достаточно во вногих случаях), например, нет метода clone() или цепочки вложенных исключений. Также, в boost есть кроссплатформенная либа для работы с системыми (OS API) ошибками через исключения. P.S. Исключение - это просто альтернативное ветвление алгоритма с побочными (нужными) действиями. Ничего особенного. Название: Re: Как пользоваться исключениями Отправлено: Авварон от Июнь 19, 2015, 18:15 Во многих случаях код Qt просто не рассчитан на возможное наличие исключения, и вы можете получить утечку памяти, крах, или неопределенное поведение. Очень удобно, да:( Название: Re: Как пользоваться исключениями Отправлено: __Heaven__ от Июнь 21, 2015, 12:33 спасибо. Достаточно подробно.
Название: Re: Как пользоваться исключениями Отправлено: sergek от Июнь 27, 2015, 13:35 Не используйте исключения в кутешном коде. А как действовать в случае использования сторонней библиотеки, в которой на каждый чих генерируется исключение?Я столкнулся с этим MQTT C++ Client. Пробовал вызовы функций библиотеки делать через обработку всех исключений, например: Код: try{ Название: Re: Как пользоваться исключениями Отправлено: Akon от Июнь 27, 2015, 16:26 Потому что ABI получился различным. Что в либе (dwarf, sjlj), и что в программе?
Название: Re: Как пользоваться исключениями Отправлено: Igors от Июнь 27, 2015, 17:21 Потому что ABI получился различным. Что в либе (dwarf, sjlj), и что в программе? Вот когда знатоки бросают такие фразы... ну я прямо теряюсь :) Вот мои скудные познания ABI - набор правил/соглашений по вызовам (типа что на каком регистре ожидает callee). Как он может "получаться" различным ??? Либа может быть совместима по ABI или нет - и тогда ее никак не приспособить. dwarf - видел в установках, формат отладочной информации sjlj - никогда не слыхал о таком Растолкуйте плиз что я не так понимаю. Спасибо Название: Re: Как пользоваться исключениями Отправлено: Akon от Июнь 27, 2015, 18:02 Когда вы пишите try/catch компилятор создает дополнительные служебные структуры данных, помещаемые на стеке (или еще в каких секциях). Если исключение переходит границу модулей, то формат этих структур должен быть идентичен для этих модулей. Для поддержки исключений компилятор может использовать разные механизмы, например, MSVC использует SEH - это вообще механизм ОС. В этом случае, например, throw в конечном счете трансформируется в вызов API RaiseException, а catch - в соостветствующие фильтры __except. Как вы понимаете, это все ABI.
Название: Re: Как пользоваться исключениями Отправлено: sergek от Июнь 27, 2015, 22:44 Когда вы пишите try/catch компилятор создает дополнительные служебные структуры данных, помещаемые на стеке (или еще в каких секциях). ... Круто. И библиотека, и программа, использующая библиотеку, собраны одним компилятором - mingw.Название: Re: Как пользоваться исключениями Отправлено: Akon от Июнь 27, 2015, 23:30 Вы сами собирали?
Название: Re: Как пользоваться исключениями Отправлено: sergek от Июнь 28, 2015, 14:13 Вы сами собирали? Да.Название: Re: Как пользоваться исключениями Отправлено: Akon от Июнь 28, 2015, 14:56 А при каком типе исключения валится? Если вставить в самое начало ф-ии
client.subscribe(subTopic, QOS, nullptr, subListener); throw std::exception(); что будет? Название: Re: Как пользоваться исключениями Отправлено: sergek от Июнь 28, 2015, 17:00 На этом типе и валится:
terminate called after throwing an instance of 'mqtt::exception' what(): std::exception Но сейчас вставлю в функцию throw, посмотрим. upd: все то же самое. Название: Re: Как пользоваться исключениями Отправлено: Igors от Июнь 28, 2015, 17:28 На этом типе и валится: Был в похожей ситуевине (вот валится на любом испускании), методом втыка нашел что помогает выключить "dead strip code" (ну это в терминах Xcode, как в mingw не в курсе). Т.е. просто баг компилятора (точнее линкера). terminate called after throwing an instance of 'mqtt::exception' what(): std::exception Но сейчас вставлю в функцию throw, посмотрим. upd: все то же самое. Конечно шансов что у Вас то же самое очень мало. Самое мерзкое в этих исключениях - что разобраться "логически" (не побоюсь этого слова :)) - просто не видно как. Отладчик или вообще потерял стек или наводит на какие-то исходники куда Макар телят не гонял. Такие залеты отливаются в неск дней "плясок с бубном", и приходят соображения типа "та ну его нафиг, пусть будет менее стройно зато с отладкой без проблем". Название: Re: Как пользоваться исключениями Отправлено: sergek от Июнь 28, 2015, 17:54 В принципе, библиотека не очень большая. Можно все исключения заменить на возврат кодов.
Наверное, так и сделаю потом. Не очень удобно - с каждой новой версией придется вносить правки. Название: Re: Как пользоваться исключениями Отправлено: Akon от Июнь 29, 2015, 09:33 Ну хорошо, а если в библиотеке написать свою функцию и оттуда выбросить исключение?
Да проблема с флагами сборки. Заменять исключения на коды ошибок считаю не вариант. Название: Re: Как пользоваться исключениями Отправлено: sergek от Июнь 29, 2015, 12:20 Да проблема с флагами сборки. Заменять исключения на коды ошибок считаю не вариант. Одинаково все. По крайней мере, что касается исключений. Вот проекты.В принципе, могу и исходники, но вам это будет гиморно - нужно установить брокер, собрать библиотеки (C и C++). |