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