C++. Бархатный путь. Часть 2 - Ошибки и исключительные ситуации
ОГЛАВЛЕНИЕ
Ошибки и исключительные ситуации
Мы завершаем путь. Всё это время мы стремились не допускать ошибок в выражениях, операторах, объявлениях, определениях, макроопределениях, программах. Но до сих пор у нас нет чёткого представления о том, что такое ошибка.
В общем случае под ошибкой мы будем понимать несоответствие правилу, алгоритму. Это рабочее определение. Конечно, правила бывают нечёткими, алгоритмы - некорректными. Это неважно. В любом случае можно сказать, что "всё не так, как должно быть". И этого достаточно.
Разные ошибки проявляют себя по-разному и могут быть обнаружены в разное время, на разных стадиях жизненного цикла программы и при различных обстоятельствах.
Выявлением некорректных макроопределений, несуществующих заголовочных файлов и неверных условий компиляции занимается препроцессор. Ошибки препроцессора выявляются на ранних этапах трансляции. Сами по себе они не проявляются.
Транслятору C++ хорошо известен синтаксис языка. Поэтому нарушение правил порождения слов, выражений и предложений, в том числе и неуместное использование ключевых слов, достаточно легко обнаруживается на стадии трансляции.
Транслятор распознаёт константные выражения различной сложности. Он способен самостоятельно производить арифметические вычисления. Так что с вопросами определения статических массивов также не возникает никаких проблем.
На этапе трансляции распознаются леводопустимые выражения. Поэтому значительная часть ошибок, связанных с некорректным использованием операций присвоения также выявляется на стадии трансляции.
Многие ошибки несоответствия типов также могут быть выявлены на этапе трансляции, в ходе создания объектного кода. Здесь следует вспомнить об операции явного преобразования типа, которая отключает контроль транслятора за типами.
На этапе создания исполнительного модуля программа (или система) компоновки способна распознать объявленные и неопределённые переменные и функции, а также незавершённые объявления классов.
В ряде случаев на этапе создания объектного кода могут выявляться неопределённые и неиспользуемые переменные, и даже потенциально опасные фрагменты кода. Транслятор может предупредить об использовании в выражениях неинициализированных переменных.
Однако не все расхождения с правилами, идеальным схемами и алгоритмам могут быть обнаружены до того момента, пока программа находится в состоянии разработки.
Существует категория ошибок, которые не способны выявить даже самые изощрённые препроцессоры, трансляторы и программы сборки. К их числу относятся так называемые ошибки времени выполнения. Эти ошибки проявляются в ходе выполнения программы.
Мы не раз подчёркивали, что в C++ часто возникают ситуации, при которых ответственность за правильность выполнения операций, операторов и даже отдельных функций целиком возлагается на программиста. Арифметические вычисления (деление на нуль), преобразования типа, работа с индексами и адресами, корректная формулировка условий в операторах управления, работа с потоками ввода-вывода - это далеко не полный перечень неконтролируемых в C++ ситуаций.
Ошибки времени выполнения, возникающие непосредственно в ходе выполнения программы, в терминах объектно-ориентированного программирования называются исключительными ситуациями. Исключительные ситуации - это события, которые прерывают нормальный ход выполнения программы.