Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Коллеги! Давайте обсудим C++ exceptions. 1) Best practices. 2) Антипаттерны. В рамках продолжения Идеология С++ и warnings ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 17:59 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Исключения, как уже отмечали, появились не в плюсах и появились они для того, чтобы отделить "рабочий поток исполнения" и "обработку ошибок". Можно имитировать через setjump/longjump, но возникают проблемы с деструкторами объектов: всё, что компилятор трудолюбиво заготовил на стеке - идёт лесом. Можно имитировать "циклом с прерыванием" - будет минимальное "замусоривание" кода тривиальными вставками вида: Код: sql 1. Насколько я понимаю, в обоих вариантах будут проблемы с многопоточным кодом. "Как-то так". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 18:20 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Добавлю еще пункт. 3) Неперехваченный exception в конструкторе. Будет-ли создан объект? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 18:46 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
"Выполнение кода остановится в точке генерации исключения. Деструкторы не вызываются, если конструктор не отработал до конца" - не дословная цитата Скотта Мейерса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 18:49 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
За что я не люблю исключения: 99.(9)% людей не умеют их использовать. В большинстве учебников исключения объяснены на примерах типа такого: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Все мило и замечательно, четко, понятно и вообще красиво. Но после этого, в реальном коде люди постоянно пишут текст типа: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. И потом начинают кручиниться: "А как узнать почему именно упали? Мы не смогли найти файл? Не смогли прочитать его? Не смогли записать? Или произошло что-то еще не связанное с файлом?" Вот вам конкретный пример такого человеческого поведения: 17179694 . Дмитрий застрял именно на том, что у него есть несколько однотипных операций, все они способны выкинуть одно и то-же исключение. Но ему надо понять какая конкретно операция упала, а он не может этого сделать. Почему не может, хотя метод решения лежит на поверхности? Потому что он привык что в try{}catch блоке находится несколько операторов. И обработка ошибок ВСЕГДА идет по окончанию блока. Ну вот привык человек и все. Как дополнительный пример этой же самой проблемы, можно ткнуть пальцем в статью Завалишина опубликованную аж в 97-ом, и до сих пор еще читаемую: 17185154 . В статье много эмоций, но... Берем самое начало статьи "Как это делают в С++". Завалишин предлагает два примера (номера 4 и 5) в качестве иллюстрации как удобно с исключениями и как не удобно без них. И на первый взгляд он прав - код с исключениями короче... но.... если чуть-чуть приглядеться, то видно что примеры разные и решают разные задачи по разным алгоритмам. Причем работа надо ошибками в пятом примере более качественная чем в четвертом примере. Вторая гигантская проблема исключений это то что их можно перекидывать на уровень выше: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. А теперь попробуйте сказать, какой из вызовов foo1() упал. Тот который был вызван напрямую из foo3() или тот который вызывался через посредничество foo2()? Примеров подобных вопросов на форуме я сейчас с ходу не нашел, но все кто занимается поддержкой существующего софта встречались с этой проблемой. Вы можете спросить: ну так а что мешает разрезать пример с обновлением файла на три try{}catch блока? И что мешает написать foo2() во втором примере так чтобы он сам ловил исключение в foo1() и кидал в свою очередь более информативное исключение? Ответ: ничего не мешает кроме привычек. Человек привыкший к работе с кодами возврата всегда думает в каком логическом блоке он находится. И с самого начала обработает ошибку по месту ее возникновения. При работе с кодами возврата мы вынуждены думать где мы сейчас находимся и что надо делать в случае потенциальной проблемы. А у человека привыкшего к исключениям такого навыка просто нет. В учебнике сказано что обработку ошибок можно делать в самом конце? Значит мы всегда будем ее делать в самом конце и не важно правильно ли это. Да, используя исключения можно написать хорошую и качественную программу. Теоретически это возможно. Но к сожалению, в реальности это практически не встречается. Для правильной работы с исключениями надо понимать что они работают не так как думает человек. Не просто знать, а понимать, чувствовать, принять как дыхание. Мы, люди, когда пишем в программе: Код: plaintext 1. 2. 3. 4. 5. 6. 7. Мысленно проговариваем про себя: "вызвали call1(), если упали идем в блок catch, потом вызвали call2(), если упали идем в блок catch, и наконец вызвали call3(), если упали идем в блок catch." И мы думаем что это все именно так и происходит. Но к сожалению, это вовсе не так. На самом деле этот код означает "Если мы попали в catch, значит какой-то кусок, какой-то из функций не отработал. Причем мы не знаем конкретно какая из функций call1, call2 или call3 не доработала до конца и в какой степени эта функция не отработала до конца". Если вы сумеете перестроить свое сознание на правильное понимание что такое исключение - вы сможете писать хорошие программы с ними. Практика показывает что таких людей на свете единицы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 19:55 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
White Owl, в данном примере хотелось-бы чтобы компиллятор сделал Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Или что-то в этом роде. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 20:34 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
White OwlЗа что я не люблю исключения: 99.(9)% людей не умеют их использовать. Ггггггг Гигантская проблема исключений то что эти 99.9% считают что уж они то умеют. И потом по форумам рассказывают небылицы. Например про то, что то, ради чего исключения и были придуманы, и без чего они вообще никому не нужны, оказывается - это гиганская проблема: White OwlВторая гигантская проблема исключений это то что их можно перекидывать на уровень выше Еще раз повторю то что писал уже в том топике другими словами. Чем дальше уровень вложенности где ловятся исключения от уровня где они бросаются, тем правильнее исключения используются. И верхним уровням никогда не требуется знать где конкретно произошло исключение нижнего уровня. Если вам требуется - то у вас дизайн программы сделан через одно место. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 20:59 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
mayton Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Вот это пример антипаттерна. Когда ловля исключений используется только для отладки. Для этого вообще то логирование существует. Данный код должен выглядеть так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Никаких try catch тут не надо вообще. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 21:06 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
В исключениях есть минусы: 1. нижний уроверь имеет больше конкретики о причине исключения. 2. освобождение ресурсов ОС. Хотя если обернуть все в классы, то решаемо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 21:09 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Dima T2. освобождение ресурсов ОС. Хотя если обернуть все в классы, то решаемо. Если используются исключения всегда должно применяться RAII. Иначе смысла в них нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 21:36 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyВот это пример антипаттерна. Когда ловля исключений используется только для отладки. Для этого вообще то логирование существует. Данный код должен выглядеть так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Никаких try catch тут не надо вообще. Ну вроде как по пункту (2) отметились. Повестка двигается. А теперь вопрос. Что это за объект такой logger? И зачем он мне нужен? Я не хочу никаких логгеров. Мне выводить - некуда. Нет у меня файловой системы. Вот такие вот условия. Может быть такое быть? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 22:39 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
2 Белый Сова. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Ну... если-б каждый метод подсистемы IO бросал свой уникальный expeption. Код: plaintext 1. 2. 3. 4. 5. То мы могли-бы ловить в коде некий общий тип исключений и позиционироваться более конкретно. Но опять-же... если в блоке try мы работаем с двумя файлами.... :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 23:05 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonWhite Owl, в данном примере хотелось-бы чтобы компиллятор сделал Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Или что-то в этом роде.Нет. Этого не достаточно. Падение произошло внутри одной из функций. Мало знать какая функция упала, надо еще знать почему она упала. Это более-менее хорошо сделано в java, где исключение автоматоматически собирает полный стек вызовов при передаче на верхние уровни. Там уже действительно можно пройти по списку и действительно найти истинный источник ошибки. В С++ это можно сделать и вручную конечно, но это надо делать. В жизни с кодами возврата конечно все намного труднее потому что там вообще все надо делать вручную. Но в этом и плюс - ты всегда знаешь что если надо ошибку передать наверх, ты будешь ее передавать наверх. Сам. Вручную. Перед этим обдумав. А не просто махнув рукой: "Здесь мы работаем с фигулькой которая может глюкнуть. Но мне лениво сейчас разбираться как это обработать. Выкину исключение, пусть мой коллега который будет работать с этой функцией разбирается". Тот перекидывает исключение выше, а в итоге оно если и обрабатывается, то уже никому не известно откуда оно родилось. Повторюсь еще раз. С исключениями можно работать, но надо думать что делаешь. Учебники (и форумные гуру) представляют исключение как очень простую и удобную штуку. Как результат: люди используя исключения не пытаются видеть полную картину своей программы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 23:15 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyWhite OwlЗа что я не люблю исключения: 99.(9)% людей не умеют их использовать. Ггггггг Анатолий, прочитайте мой пост еще раз. И на этот раз не по диагонали, и не ограничиваясь примерами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 23:17 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
mayton2 Белый Сова. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Ну... если-б каждый метод подсистемы IO бросал свой уникальный expeption. Код: plaintext 1. 2. 3. 4. 5. То мы могли-бы ловить в коде некий общий тип исключений и позиционироваться более конкретно. Но опять-же... если в блоке try мы работаем с двумя файлами.... :( Вот именно потому что мы работаем с файлам два раза (или с двумя файлами) и еще с неким алгоритмом обрабатывающим строку, данный код по хорошему должен выглядеть так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. Но... Вот наглядный пример, ты сам. С++ знаешь, с исключениями работать умеешь, но пошел по пути создания множества дополнительных исключений. Почему? Что тебе помешало разбить алгоритм на блоки и сделать для каждого свой обработчик? Я со своей привычкой к кодам возврата обошелся одним дополнительным, ты сделал пять дополнительных и сам испугался. Почему? Потому что привык что все исключения обрабатываются в конце. Так в учебниках пишут... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 23:32 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Тогда делаем макрос Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Хотя возможно до меня этот макрос (класс или шаблон или функцию) уже где-то делали. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2015, 23:41 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonТогда делаем макросНафиг-нафиг. Наша цель же упростить программирование и не потерять гибкости. Макрос, особенно такой, это усложнение. Так что нафиг-нафиг. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 00:48 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonА теперь вопрос. Что это за объект такой logger? И зачем он мне нужен? Я не хочу никаких логгеров. Мне выводить - некуда. Нет у меня файловой системы. Вот такие вот условия. Ну тогда вам сначала надо применить это условие по отношению к вашей функции message() ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 07:35 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
White OwlАнатолий, прочитайте мой пост еще раз. И на этот раз не по диагонали, и не ограничиваясь примерами. Ну вот читаю еще раз. White OwlНо ему надо понять какая конкретно операция упала, а он не может этого сделать. Это нужно программисту расследующему баги. И это решается логированием, как я выше привел. А вот зачем самой функции в процессе выполнения это знать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 07:53 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
White OwlЗа что я не люблю исключения: 99.(9)% людей не умеют их использовать. ... Практика показывает что таких людей на свете единицы.прекрасный спич, но практика показывает, что 99.(9)% вообще не обрабатывают ошибки времени выполнения. Коды возврата технично игнорируются и программа падает в непредсказуемом месте из-за деления на 0 или по защите памяти, к примеру. В большой степени это происходит из-за того, что довольно нудно обрабатывать после каждого вызова этот самый код ошибки. catch в конце блока хотя бы гарантирует, что сломалось где-то здесь, и дальше этого места ошибка не распространится. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 09:43 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyWhite OwlНо ему надо понять какая конкретно операция упала, а он не может этого сделать. Это нужно программисту расследующему баги. И это решается логированием, как я выше привел. А вот зачем самой функции в процессе выполнения это знать?+1. Золотые слова )) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 09:44 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Исключения в C++ состоитят из двух частей 1.механизм 2.имплементация в стандартной библиотеке. Первое сделано хорошо, второе нет. Можно добавить логирование backtrace() и __LINE__ при генерировании своих исключений. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 10:24 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
egorychAnatoly Moskovskyпропущено... Это нужно программисту расследующему баги. И это решается логированием, как я выше привел. А вот зачем самой функции в процессе выполнения это знать?+1. Золотые слова )) выдать одну ошибку кастомеру "Ваша программа неработает" ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 10:26 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
OoCcegorychпропущено... +1. Золотые слова )) выдать одну ошибку кастомеру "Ваша программа неработает" ? Уже говорили выше. Я-бы добавил что стоит различать просто факт возникновения ошибки (например SocketException). После этого, метод выболняющий к примеру softwareupdate молча уходит в ожидание. Мало-ли что там с сетью. WiFi отвалился. И второй вариант - это как сказано выше для анализа ошибок разработчиком. В этом варианте я не просто хотел-бы получить __LINE__ где "стрельнуло" но и "посмертный снимок" стека. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 10:31 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
OoCcвыдать одну ошибку кастомеру "Ваша программа неработает" ? Нет. Выдать юзеру что такое-то действие выполнено с ошибкой. Например юзер сохраняет файл, а места на диске нет. Ему выдается "Ошибка сохранения (нет места)" При этом ни юзеру ни коду который это показывает совершенно не нужна информация о том в каких глубинах нижележащего кода брошено исключение IOException("Нет места") . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 10:37 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonOoCcпропущено... выдать одну ошибку кастомеру "Ваша программа неработает" ? Уже говорили выше. Я-бы добавил что стоит различать просто факт возникновения ошибки (например SocketException). После этого, метод выболняющий к примеру softwareupdate молча уходит в ожидание. Мало-ли что там с сетью. WiFi отвалился. И второй вариант - это как сказано выше для анализа ошибок разработчиком. В этом варианте я не просто хотел-бы получить __LINE__ где "стрельнуло" но и "посмертный снимок" стека. "посмертный снимок" - это отладка и к стандарту языка никакого отношения не имеет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 10:48 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
OoCcвыдать одну ошибку кастомеру "Ваша программа неработает" ?вот, это то, что я обычно вижу в коде, основанном на обработке кодов ошибок. Ну нудно же каждый раз разбирать их все, поэтому проще долбануть мессаджбокс с подобным бессмысленным текстом, что ничем не отличается от catch(...), кстати. В связи с этим аргументация в ( вечном ) споре о том, что лучше коды ошибок или исключения, основанная на том, что какой-то из этих методов провоцирует плохой стиль программирования, а другой - нет, это чушь и популизм. Хорошие программы можно написать, используя любой из этих подходов, а уж плохие - тем более )) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 11:43 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyOoCcвыдать одну ошибку кастомеру "Ваша программа неработает" ? Нет. Выдать юзеру что такое-то действие выполнено с ошибкой. Например юзер сохраняет файл, а места на диске нет. Ему выдается "Ошибка сохранения (нет места)" При этом ни юзеру ни коду который это показывает совершенно не нужна информация о том в каких глубинах нижележащего кода брошено исключение IOException("Нет места") . Логично. В идеальном мире все очень здорово. В реале, в глубинах нижележащего кода может возникнуть масса других исключений. Не связанных с нехваткой места. В результате обьем кода обработки ошибок будет приближаться к C с одной стороны и нагрузка в рантайме будет выше чем в С с другой стороны. И к тому же может возрасти трудоемкость (стоимость) дизайна. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 12:26 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
egorychВ связи с этим аргументация в ( вечном ) споре о том, что лучше коды ошибок или исключения, основанная на том, что какой-то из этих методов провоцирует плохой стиль программирования, а другой - нет, это чушь и популизм. Хорошие программы можно написать, используя любой из этих подходов, а уж плохие - тем более )) +1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 12:40 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonИ второй вариант - это как сказано выше для анализа ошибок разработчиком. В этом варианте я не просто хотел-бы получить __LINE__ где "стрельнуло" но и "посмертный снимок" стека. Стек не всегда помогает - иногда нужен полный дамп процесса По виндой использую во такие штуки: https://code.google.com/p/crashrpt/ https://drdump.com/crash-reporting-system Кто не пробовал - рекомендую. помогает вычислять много хитрых ошибок которые не повторяются на компе разработчика. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 13:07 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
OoCc"посмертный снимок" - это отладка и к стандарту языка никакого отношения не имеет. Не согласен с тезисом. ЯП должен "иметь возможность" детализировать ошибку. Будь это debug mode или еще что-либо. Привожу пример. В тестовой конфигурации не удаётся воспроизвести ошибку. (Очень типично). Ни нагрузка ни датасорсы не могут создать условия. Единственный кейс - снять максимум полезный инфы с продуктива. Что-то упало на проде. Главный вопрос. Что? Где? Какая библиотека. Какой метод. Какая строка. И не ОС а именно ЯП должен предоставлять ВОЗМОЖНОСТЬ собрать такой код. Пускай даже бинарник станет немного больше. Мы идём на такие жертвы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 13:09 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonЧто-то упало на проде. Главный вопрос. Что? Где? Какая библиотека. Какой метод. Какая строка. И не ОС а именно ЯП должен предоставлять ВОЗМОЖНОСТЬ собрать такой код.три вопроса: * С++ не позволяет собрать такой код, ты считаешь? * или использование исключений не позволяет собрать такой код? * в какой ЯП это встроено из коробки, чтобы можно было сказать - вот идеал, и надо так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 13:58 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Это был ответ товарищу ОоСс по поводу отладки и стандартов языка. Я говорю - "как должно" быть в моём понимании. Во всех языках. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 14:01 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
White OwlВот вам конкретный пример такого человеческого поведения: 17179694 . Дмитрий застрял именно на том, что у него есть несколько однотипных операций, все они способны выкинуть одно и то-же исключение. Нет, это совсем не такой пример. Во-первых, эти операции не выкидывают исключения, а только "сообщают, что они выполнились успешно, но с какими-то нюансами". Во-вторых, мне там совершенно пофиг какая операция имела нюансы, достаточно вывалить пользователю или в лог сообщение "были такие-то нюансы, но мы работаем дальше". Вот это "работаем дальше" в случае с исключениями довольно хреново (криво) программируется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 14:15 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonOoCc"посмертный снимок" - это отладка и к стандарту языка никакого отношения не имеет. Не согласен с тезисом. ЯП должен "иметь возможность" детализировать ошибку. Будь это debug mode или еще что-либо. Привожу пример. В тестовой конфигурации не удаётся воспроизвести ошибку. (Очень типично). Ни нагрузка ни датасорсы не могут создать условия. Единственный кейс - снять максимум полезный инфы с продуктива. Что-то упало на проде. Главный вопрос. Что? Где? Какая библиотека. Какой метод. Какая строка. И не ОС а именно ЯП должен предоставлять ВОЗМОЖНОСТЬ собрать такой код. Пускай даже бинарник станет немного больше. Мы идём на такие жертвы. ВОЗМОЖНОСТЬ - это возможность конкретного компилятора и библиотеки поддержки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 14:17 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Они не криво программируются. А скорее не решают других вопросов. Например ЧТО ДЕЛАТЬ в блоке catch(...){}. Здесь наверное мнения мемберов этого топика уже РАЗДЕЛЯТСЯ даже в тривиальном примере. Скорее всего само содержание catch должно наполнятся смыслом только в контексте решаемой задачи. Дать рекомендации по catch "в общем" нет никакой возможности. Что с мемори? Что с файлами? Что с сокетами? Что закрыать. Что освобождать. Эскалировать наверх? Что эскалировать? Тоже самое? Или обобщённое? Или форматировать "лопух" с "баттоном" для гуи? Логгировать? С каким уровнем? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 14:22 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonЭто был ответ товарищу ОоСс по поводу отладки и стандартов языка. Я говорю - "как должно" быть в моём понимании. Во всех языках.а, понял, прости ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 14:27 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
White OwlПадение произошло внутри одной из функций. Мало знать какая функция упала, надо еще знать почему она упала. Кто мешает тебе во время выбрасывания исключения сохранить эту важную информацию (где и почему) внутри самого исключения? White OwlЭто более-менее хорошо сделано в java, где исключение автоматоматически собирает полный стек вызовов при передаче на верхние уровни. Кто мешает тебе в С++ сделать то же самое ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 15:53 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonА теперь вопрос. Что это за объект такой logger? И зачем он мне нужен?Для отладки того, что не может быть пройдено в отладчике.Я не хочу никаких логгеров. Мне выводить - некуда. Нет у меня файловой системы. Вот такие вот условия. Может быть такое быть?Нет, не может - если вам нужна отладка, то вы обязаны обеспечить приём и обработку отладочных сообщений. И на файловой системе свет клином не сошёлся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 17:59 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
White OwlПадение произошло внутри одной из функций. Мало знать какая функция упала, надо еще знать почему она упала. Это более-менее хорошо сделано в java, где исключение автоматоматически собирает полный стек вызовов при передаче на верхние уровни. Там уже действительно можно пройти по списку и действительно найти истинный источник ошибки. В С++ это можно сделать и вручную конечно, но это надо делать.Не надо использовать исключения для отладка, а если этого не делать, то есть всего две ситуации: 1. Мой косяк и это будет необработанное исключение. Трасса стека, конечно, упрощает поиск места возникновения исключения, но совершенно не требуется, чтобы знать где и что упало. 2. Реальная жизнь и я должен знать, что делать с каждым возможным исключением. И каждое такое исключение должно быть обработано, даже если обработка заключается в том, чтобы ничего не делать в catch-блоке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 18:07 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonВ тестовой конфигурации не удаётся воспроизвести ошибку. (Очень типично). Ни нагрузка ни датасорсы не могут создать условия. Единственный кейс - снять максимум полезный инфы с продуктива.Я повторю то, что уже озвучивал: протоколирование должно проектироваться и разрабатываться наравне с основным кодом. Если имеющихся ресурсов недостаточно - надо делать протоколирование под конкретную проблему.Что-то упало на проде. Главный вопрос. Что? Где? Какая библиотека. Какой метод. Какая строка.Реальный случай. Ловим NPE, отдаём разработчику трассу, где есть "... line 3 35 ". Получаем исправление, работаем дальше и получаем новое NPE с трассой "... line 3 55 ". Всё остальное идентично - и место и причина и ошибка. Мораль: отправь дурака за бутылкой, так он, дурак, одну и принесёт. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 18:16 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Ну... правильно. Он с вас 10$ взял за первый NPE. И еще десятку за второй. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 18:22 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonНу... правильно. Он с вас 10$ взял за первый NPE. И еще десятку за второй.Это был контракт с фиксированной суммой поддержки, в которую входит исправление ошибок. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 18:26 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Понимешь. Там был костыль. И он подпёр этот костыль другим костылём. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 18:27 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonПонимешь. Там был костыль. И он подпёр этот костыль другим костылём. Не. Он добавил 20 строк комментов с описанием какая в этой строке происходит ошибка :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 18:30 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonПонимешь. Там был костыль. И он подпёр этот костыль другим костылём.Понимаешь, я лучше знаю причину ошибки и, что ещё важнее - условия её возникновения. Поэтому могу утверждать, что костыля не было - был один и тот же косяк в двух местах одного файла на расстоянии двадцати строк (один экран). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 18:31 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Ну а какая мораль? Заставить его фиксить все NPE в методе? Модуле? Библиотеке? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 18:35 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonНу а какая мораль?Точное знание места возникновения ошибки слабо связано с качественностью её устранения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 18:39 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Может мы далеко вперёд забегаем? Я тут переживал за идентификацию "места" исключения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 18:41 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonЯ тут переживал за идентификацию "места" исключения.Исключения полезны тогда, когда мы можем разделить "нормальный" и "ошибочный" потоки исполнения. Если нам требуется знать место исключения, то или мы не правы в своих желаниях или нам требуется протоколирование. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 18:48 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Неужели я покину этот топик неудовлетворённым. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 18:54 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Если мы написали try/catch, то во всём охраняемом блоке однотипные исключения обрабатываются идентичным образом. Если это не так, то или требуется более одного охраняемого блока или нам нужны не исключения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 18:57 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyWhite OwlАнатолий, прочитайте мой пост еще раз. И на этот раз не по диагонали, и не ограничиваясь примерами. Ну вот читаю еще раз. White OwlНо ему надо понять какая конкретно операция упала, а он не может этого сделать. Это нужно программисту расследующему баги. И это решается логированием, как я выше привел.Угу, логирование это хорошо. Но логирование это ручная операция. А исключения полу-автоматическая с поддержкой на уровне языка. Исключения могут служить для целей логирования, но... Anatoly MoskovskyА вот зачем самой функции в процессе выполнения это знать?Затем, что некоторые ошибки времени выполнения не являются смертельными и могут быть обработаны автоматически. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 19:00 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
MasterZivWhite OwlПадение произошло внутри одной из функций. Мало знать какая функция упала, надо еще знать почему она упала. Кто мешает тебе во время выбрасывания исключения сохранить эту важную информацию (где и почему) внутри самого исключения?Если проблему отловил мой код - то ничто не мешает. А если проблема случилась внутри библиотечной функции, то я уже никак не могу повлиять на созданное исключение. Я могу только перехватить его послать вместо него свое собственное, которое локализует проблему до уровня "какая функция упала", но не более того. MasterZivWhite OwlЭто более-менее хорошо сделано в java, где исключение автоматоматически собирает полный стек вызовов при передаче на верхние уровни. Кто мешает тебе в С++ сделать то же самое ?Ничто не мешает. И если я работаю в проекте с исключениями - всегда веду полный трейс. Правда я редко с такими проектами работаю :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 19:09 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
White OwlAnatoly MoskovskyА вот зачем самой функции в процессе выполнения это знать?Затем, что некоторые ошибки времени выполнения не являются смертельными и могут быть обработаны автоматически. Ну так обрабатывайте, зачем знать откуда брошено исключение? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2015, 19:11 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyWhite Owlпропущено... Затем, что некоторые ошибки времени выполнения не являются смертельными и могут быть обработаны автоматически. Ну так обрабатывайте, зачем знать откуда брошено исключение?Чтобы знать как его обрабатывать. Одинаковые ошибки произошедшие в разных местах могут потребовать разной обработки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 00:16 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
White OwlЧтобы знать как его обрабатывать. Одинаковые ошибки произошедшие в разных местах могут потребовать разной обработки. Еще раз. Зачем верхнему уровню абстракции знать где именно на нижнем уровне брошено исключение, если верхний уровень вообще не должен знать устройство нижнего? Сделайте нормальную декомпозицию и эта нужда отпадет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 07:58 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Вообще конечно смешно наблюдать, как человек, который ненавидит и С++ и концепцию исключений, рассказывает как должны быть устроены исключения и как их правильно применять в С++ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 08:14 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Толик я вообще не понял к чему этот пост? Или к кому? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 14:14 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonТолик я вообще не понял к чему этот пост? Или к кому? А просто так. У нас же здесь все просто так. Кто-то в форуме по С++ рассуждает про то как оптимизаторы СУБД используют индексы. А я вот про это. И самое главное что все в рамках топика - про С++ и исключения ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 14:42 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Можно тебя попросить не писать просто так вещи которые могут задеть или обидеть меня или мемберов? Модератор: Break. Ничего обидного не было и, надеюсь, не будет. Так что поссориться нам не удастся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 15:02 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
White OwlAnatoly Moskovskyпропущено... Ну так обрабатывайте, зачем знать откуда брошено исключение?Чтобы знать как его обрабатывать. Одинаковые ошибки произошедшие в разных местах могут потребовать разной обработки. Ну ты вот всё время приводишь проблемы, которые одинаково возникают и при использовании исключений, и при использований кодов возврата. Так что исключения там или нет -- по барабану. Коды возврата же накладывают два дополнительных ограничения: каждая функция должна принимать дополнительный параметр для возврата кода ошибки или должна не быть функцией (возвращаемое значение будет кодом возврата). после вызова каждой функции надо проверять код возврата. При каскадном вызове функций -- при каждом вложенном вызове. Исключения же накладывают только одно дополнительное ограничение -- ими нужно уметь пользоваться: исключения должны генерироватья только в случае, если нормальное течение потока управления не может продолжаться. Ну очевидно же, что исключения более гибкие. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 15:19 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonТолик я вообще не понял к чему этот пост? Или к кому? К нашему Мудрому Сову, естественно. Ну не любит человек исключения. Не любит, не понимает, и не хочет понимать. Или уже понял, но нелюбовь осталась. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 15:21 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Ну что-ж продолжим обсуждать исключения. Давайте коснёмся перформанса. Исключения в цикле e.t.c. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 15:27 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonИсключения в цикле e.t.c. В рекурсии интереснее :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 15:31 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Dima TВ рекурсии интереснее :) Неа, интереснее форвардинг исключений из сопрограмм (coroutine). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 15:44 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
maytonДавайте коснёмся перформанса. Ну, я думаю что на данном этапе развития компиляторов, никакого существенного оверхеда исключения не вносят. Ведь это нечастое событие - вызов исключения, поэтому сколько там микросекунд оно занимает не сильно важно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 15:50 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Если исключение - это объект который нужно аллоцировать. Напихать в него свойств.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 17:43 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
MasterZivНу ты вот всё время приводишь проблемы, которые одинаково возникают и при использовании исключений, и при использований кодов возврата. Так что исключения там или нет -- по барабану.Да. Любую задачу можно решить как с исключениями, так и с кодами возврата. MasterZivКоды возврата же накладывают два дополнительных ограничения: каждая функция должна принимать дополнительный параметр для возврата кода ошибки или должна не быть функцией (возвращаемое значение будет кодом возврата). Это не обязательно. Вспомни хоть о libc с его errno и WinAPI с GetLastError(). MasterZiv после вызова каждой функции надо проверять код возврата. При каскадном вызове функций -- при каждом вложенном вызове. Это тоже не обязательно. Очень часто функция может возвращать много информационных кодов которые можно игнорировать. Да и часто бывает что несколько родственных функций запускается подряд и падение второй функции в цепочке невозможно если отработала первая. Как пример fopen()-fread(), если мы файл сумели открыть, мы всегда сумеем его прочитать (уже другое дело сколько именно байт мы прочитаем), но fread() упасть просто не сможет. Во всех этих случаях, коды возврата можно запросто игнорировать. А при работе с исключениями эта проверка будет всегда, ее компилятор насильно в твой код впихнет. MasterZivИсключения же накладывают только одно дополнительное ограничение -- ими нужно уметь пользоваться: исключения должны генерироватья только в случае, если нормальное течение потока управления не может продолжаться. Угу. А как быть с информационными сообщениями? Тот же SQL_SUCCESS_WITH_INFO если ты делаешь враппер для ODBC? Делать такие возвраты как исключения или как коды возврата в дополнение к исключениям которые будут перекрывать SQL_ERROR? И перевирая твои слова: Ну очевидно же, что кода возврата более гибкие. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 19:30 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskymaytonДавайте коснёмся перформанса. Ну, я думаю что на данном этапе развития компиляторов, никакого существенного оверхеда исключения не вносят. Ведь это нечастое событие - вызов исключения, поэтому сколько там микросекунд оно занимает не сильно важно.Да при чем здесь вызов исключения то? Как по твоему организован try{}catch блок? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Чтобы исключение поймать, надо сначала узнать что оно есть. И наличие проверки на появилось ли исключение или нет, никак не зависит от практического создания исключения. И кстати, для полноты картины: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Функционально тоже самое что и языко-поддерживаемые исключения, но в "ручном" режиме. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 19:40 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
White OwlА как быть с информационными сообщениями? Тот же SQL_SUCCESS_WITH_INFO если ты делаешь враппер для ODBC? Делать такие возвраты как исключения или как коды возврата в дополнение к исключениям которые будут перекрывать SQL_ERROR? Ни то ни другое. Вот эти инфо - это данные, один из результатов работы функции, а не код ошибки. Поэтому должен быть предусмотрен АПИ для доступа к этому результату, специально разработанный для удобства пользования им, т.е. ответ зависит от того для чего нужно получать эту инфу и можно ли ее игнорировать вообще. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 19:45 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Коллеги. Немного отвлеку вас. По смыслам. Наш аналитик часто толкает в ТЗ такие сущности. 1). Основной поток. Здесь описывается кейс приложения в случае если юзер сделал ряд кликов предусмотренных ТЗ. И получил данные. 2). Альтернативный поток . Здесь описывается кейс когда данные не найдены. Альтернатив может быть много. 3) Исключающий поток . Здесь описывается блок т.н. непредвиденной ситуации. Когда ТЗ просто не в состоянии охватить всё разнообразие ошибок workflow. Отвалился сокет. БД выкинула ORA-1555. Restful внезапно вернул общий код падения экземпляра сервера. Тут вообще может быть что угодно. Исключающий поток обладает свойством вклиниваться в любой из шагов основного или альтернативного потоков. Если-бы заказчик описывал эти кейсы на каждом шаге то ТЗ можно сделать Талмудом или Энциклопедией. И сроки вычитки и анализа отодвинуть в бесконечность. По уровням технологий. Ассемблер. Все кто кодили помнят флаговый регистр. Что-бы ты не делал - эффект каждого опкода оказывает на флажки влияние. Хочешь - обработай. Хочешь - нет. Вобщем полнейший либерализм. Цена решения - копеешная. Скорость - перфектная. Bash-скриптинг . Формально любой процесс ОС возвращает коды возврата. При неком удачном кодинге Код: python 1. будет блоком try. Если конешно кодер использовал осмысленный return из функции main(..). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 19:49 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
White OwlКак по твоему организован try{}catch блок? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Ну, наверно есть компиляторы которые так реализуют. Но мне они неизвестны. Обычно реализуется по другому. В частности, нет никаких проверок после каждого вызова. Вместо этого есть глобальный стек текущего потока в котором хранятся вызовы деструкторов в том порядке в каком их надо вызвать при развороте стека в момент бросания исключения. Этот стек обновляется при инициализации переменных блока и при выходе из блока. Там же хранятся указания какие и где ловятся исключения. Практически вся эта инфа формируется при компиляции и в рантайме просто двигается указатель. Что это значит с практической точки зрения. Например то, что если у вас есть модуль в котором все функции написаны в стиле С (более того, даже откомпилированы как С) (т.е. без объектов с деструкторами), то в этом модуле кода обвязки исключений не будет никакого вообще (а также связанного с ним хоть мизерного, но оверхеда), но при этом исключения из вызываемых им функций будут наверх передаваться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 20:03 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
2787Хотел бы поделиться своим подходом ... Конечно он не идеален, но много упрощает анализ результата выполнения функции. Над всеми libraries, которые использую создаю wrapper classes. Зачем? Их назначение одно - они инкапсулируют обработку результата выполнения функции. В результате анализ результата выполнения функции сводится к анализу member m_Ok. Если он не имеет значения TRUE, то анализируем значение m_LastErrorCode /в этом случае m_pMessageError содержит message .../ Т.е. мне не нужно думать о том, что в случае ошибки нужно вызывать GetLastError() ... ... Кстати в wrapper class состав members зависит от того в каком режиме собран exe, dll, ... /release или debug/. PS: Конечно это не панацея, но чисто субъективно /а может быть от привычки/, использую такой подход всегда. Кстати такой подход позволяет получить на выходе не просто возвращаемое значение, а в случае необходимости и несколько возвращаемых значений /правда необходимость в этом возникает редко/. Кроме того, так как мы не напрямую вызываем функции, то можно сказать мы создаем некий интерфейс над library /со всеми вытекающими из этого + и -/. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 20:31 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyWhite OwlА как быть с информационными сообщениями? Тот же SQL_SUCCESS_WITH_INFO если ты делаешь враппер для ODBC? Делать такие возвраты как исключения или как коды возврата в дополнение к исключениям которые будут перекрывать SQL_ERROR? Ни то ни другое. Вот эти инфо - это данные, один из результатов работы функции, а не код ошибки. Поэтому должен быть предусмотрен АПИ для доступа к этому результату, специально разработанный для удобства пользования им, т.е. ответ зависит от того для чего нужно получать эту инфу и можно ли ее игнорировать вообще.Ну положим что мы хотим получить наиболее удобный враппер. Твое решение? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2015, 20:33 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
White OwlНу положим что мы хотим получить наиболее удобный враппер. Твое решение? Вот тут я уже приводил пример 17179189 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2015, 01:27 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
White Owl MasterZivКоды возврата же накладывают два дополнительных ограничения: каждая функция должна принимать дополнительный параметр для возврата кода ошибки или должна не быть функцией (возвращаемое значение будет кодом возврата). Это не обязательно. Вспомни хоть о libc с его errno и WinAPI с GetLastError(). . Это ж знаменитые классыческие антипаттерны, завещаные нам прямо таки классиками. Надеюсь, ты не будешь рекомендовать людям так проектировать библиотеки. White OwlMasterZiv после вызова каждой функции надо проверять код возврата. При каскадном вызове функций -- при каждом вложенном вызове. Это тоже не обязательно. Очень часто функция может возвращать много информационных кодов которые можно игнорировать. Да и часто бывает что несколько родственных функций запускается подряд и падение второй функции в цепочке невозможно если отработала первая. Как пример fopen()-fread(), если мы файл сумели открыть, мы всегда сумеем его прочитать (уже другое дело сколько именно байт мы прочитаем), но fread() упасть просто не сможет. Во всех этих случаях, коды возврата можно запросто игнорировать. А при работе с исключениями эта проверка будет всегда, ее компилятор насильно в твой код впихнет. . Ты постоянно приводишь исключения из правил, и на их основании пытаешься доказать, что правила не действуют. Нельзя что -то так доказать или опровергнуть, мы должны находится в рамках фиксированной модели поведения функций. В данном случае мы должны предполагать, что каждая функция может завершиться нормально, или аварийно (не сделать то, что ей предписано сделать), и сигнализирует об этом либо кодом возврата, либо исключением. Если функция не завершается аварийно, то очевидно, что и говорить не о чем -- не будет либо исключений, либо кодов возврата. White OwlУгу. А как быть с информационными сообщениями? Тот же SQL_SUCCESS_WITH_INFO если ты делаешь враппер для ODBC? Делать такие возвраты как исключения или как коды возврата в дополнение к исключениям которые будут перекрывать SQL_ERROR? И перевирая твои слова: Ну очевидно же, что кода возврата более гибкие. Я объяснял, как надо поступать с диагностикой из ODBC и подобных библиотек. (в отдельной теме было) Это не исключения и не коды возврата, это дополнительный поток данных с диагностикой из источника данных. Иногда эти данные означают, что операция завершилась аварийно, тогда, только в этих случаях нужно генерировать исключение или плохой код возврата. Итого, тут нет доводов ни за исключения, ни против. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2015, 00:30 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Владимир20122787Хотел бы поделиться своим подходом ... Конечно он не идеален, но много упрощает анализ результата выполнения функции. Над всеми libraries, которые использую создаю wrapper classes. Зачем? Их назначение одно - они инкапсулируют обработку результата выполнения функции. В результате анализ результата выполнения функции сводится к анализу member m_Ok. Если он не имеет значения TRUE, то анализируем значение m_LastErrorCode Вредный подход. Ты мог бы писать такие врапера (функции, не классы), обрабатывать исключительные случаи, и выбрасывать исключения в нужных местах, где уже сохранять и код возврата, и причину ошибки. Вот это было бы по-C++-ному. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2015, 00:33 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
MasterZivВредный подход. Ты мог бы писать такие врапера (функции, не классы), обрабатывать исключительные случаи, и выбрасывать исключения в нужных местах, где уже сохранять и код возврата, и причину ошибки. Вот это было бы по-C++-ному. Кто нам мешает все это сделать в wrapper при вызове функции и затем произвести анализ на наличие ошибки или исключения в месте вызова этой функции? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2015, 09:25 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Владимир2012MasterZivВредный подход. Ты мог бы писать такие врапера (функции, не классы), обрабатывать исключительные случаи, и выбрасывать исключения в нужных местах, где уже сохранять и код возврата, и причину ошибки. Вот это было бы по-C++-ному. Кто нам мешает все это сделать в wrapper при вызове функции и затем произвести анализ на наличие ошибки или исключения в месте вызова этой функции? Как я подозреваю ты так и делал. Но это неправильно, исключения для того и придумали, чтобы не проверять. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2015, 09:49 |
|
||
|
C++ exceptions. Best practices.
|
|||
|---|---|---|---|
|
#18+
Почитал про исключения в Go Language. http://golang.org/doc/faq#exceptions Why does Go not have exceptions? We believe that coupling exceptions to a control structure, as in the try-catch-finally idiom, results in convoluted code. It also tends to encourage programmers to label too many ordinary errors, such as failing to open a file, as exceptional. Go takes a different approach. For plain error handling, Go's multi-value returns make it easy to report an error without overloading the return value. A canonical error type, coupled with Go's other features, makes error handling pleasant but quite different from that in other languages. Go also has a couple of built-in functions to signal and recover from truly exceptional conditions. The recovery mechanism is executed only as part of a function's state being torn down after an error, which is sufficient to handle catastrophe but requires no extra control structures and, when used well, can result in clean error-handling code. See the Defer, Panic, and Recover article for details. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2015, 19:33 |
|
||
|
|

start [/forum/topic.php?all=1&fid=57&tid=2019127]: |
0ms |
get settings: |
10ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
53ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
88ms |
get tp. blocked users: |
1ms |
| others: | 12ms |
| total: | 193ms |

| 0 / 0 |
