Для чего нужны проверки исключений типа std::logic_error
, если в конечной программе такие ошибки отсутствуют, т.е. делаются лишние проверки?
Хороший вопрос... С педантичной точки зрения программа действительно не должна содержать логических ошибок. Однако, понятное дело, что в реальной жизни логические ошибки вполне могут возникать. Их условно/неформально можно разделить на две группы: ошибки "непредсказуемые", возникновение которых программа не предугадала (в ответ на которые программа либо упадет, либо продолжит работать в каком-то полу-разрушенном состоянии), и ошибки "предсказуемые", когда в пользовательском коде появляется некая явно присутствующая ветка некоего if
, управление в которую никогда "не должно"/"не может" попадать. Но вдруг попадет?
Этот вопрос перекликается с другим вопросом: должны ли вызовы assert
существовать только в отладочном коде, или их следует сохранять и в релизной версии кода? Истина, как правило, располагается где-то посередине: большинство assert
в коде (в моем, как минимум) является совершенно избыточными и чересчур параноидальными "проверками на разумность" (sanity checks), которым не место в релизном коде, но некоторые из них (в основном отвечающие за проверку контрактов на входные данные функции) заслуживают того, чтобы существовать и в релизной версии.
И тогда возникает вопрос: а что делать, когда все таки такая "невозможная" ветка кода срабатывает? Вот тут-то как раз и уместна обработка уровня "логической ошибки". Это может быть немедленное завершение программы с выдачей некоего диагностического сообщения. А может быть и что-то более продвинутое, типа выбрасывания исключения класса logic_error
. Исключение может выбрасываться как с целью "прослеживания" стека вызовов, приведшего к ошибке, так и для того, чтобы аккуратно обработать ситуацию, "проглотить" исключение и все-таки продолжить работу программы. Все зависит от специфики приложения.
Хотя описание класса исключения и говорит о том, что такие ошибки скорее всего могут быть определены до выполнения программы:
These errors are presumably detectable before the program executes.
упоминание производных классов:
domain_error
(нарушение области допустимых значений)invalid_argument
(ошибочный аргумент)length_error
(превышение максимальной длины)out_of_range
(обращение к элементу вне диапазона) future_error
(ошибки асинхронных вызовов)может пролить некоторый свет на необходимость проверки подобного типа ошибок.
По мере увеличения объёма кода - увеличивается его сложность, чем сложнее программа, тем больше вероятность наличия в ней ошибки (при прочих равных условиях). Желание сделать программу "неубиваемой", т.е. чтобы даже в случае логических (алгоритмических) ошибок программа могла бы как минимум корректно завершиться (а не быть прибитой ОС), а как максимум - даже вернуться к нормальному выполнению, приводит к необходимости обвешивать каждый потенциально сбойный участок кода дополнительными проверками. Это проверки из разряда "а что если я ошибся?", по сути некий страховочный механизм.
Отловив подобную ошибку один раз - по-хорошему, требуется вносить изменения в код, чтобы второй раз та же цепочка действий уже не приводила программу в это состояние.
Идеальная программа подобного рода ошибок содержать не должна, но она вполне может приводить к ошибкам из-за неидеальности условий выполнения, например, сбой оборудования.
Как меняется крипторынок и к чему готовиться владельцам криптообменников
Задание: создать класс - двухсвязный список, создать конструктор, деструкторМетоды работы с списком: добавление, удаление элементов, сортировка...
не дает в подсказках никаких функций для рисованияМожет нужно добавить что то в библиотеки? или обьявить где то этот класс? radstudio c++builder fmx
Имеется dll-библиотека, экспортирующая функцииОна может вызывать callback-функцию, указатель на которую был передан ранее как параметр одной...
Помогите пожалуйста найти понятную литературу о ГрафахМожете объяснить хотя бы один пример на практике? Как считать матрицу смежности или...