Шаг 249.
Среда программирования Visual C++.
Упреждение ошибок

    На этом шаге мы приведем общие сведения об обработке ошибок.

    Опытные разработчики считают обработку ошибок (error handling) важным этапом процесса создания приложения, необходимым для получения надежной программы. Начиная с этого шага мы опишем основные методы обработки ошибок. Кроме того, Вы узнаете, как создавать код, который не только определяет возникновение ошибки, но и реагирует на нее должным образом (например, отображает окно сообщения). Намного проще организовать обработку ошибок во время написания приложения, чем пытаться встроить ее в программу позднее.

    Большинство опытных программистов скептически относятся к возможности написания безупречно работающего кода. В нем возможны логические ошибки, которые проявляются не сразу. Даже без них при определенных обстоятельствах программа дает сбой. Поэтому привыкайте при написании кода рассматривать все возможные варианты его работы. Пытайтесь предсказать возможные ошибки и предусмотреть обработчики, реагирующие на их появление. Эти дополнительные строки программы скорее всего будут исполняться редко, но они должны существовать на случай возникновения ошибки.

    Разработчика, не умеющего прогнозировать ошибки, можно сравнить с заснувшим на посту часовым. Рассмотрим типичный случай - функция выделяет память для буфера, который затем заполняется текстом. Она получает указатель на область памяти оператором new и немедленно начинает записывать в нее данные. На компьютере разработчика она выполняется безупречно, ведь на нем много памяти. Но вот программа поступила в продажу, и разработчику начинают звонить разгневанные пользователи, потерявшие целый день из-за сбоев программы, которой не хватает памяти.

    Опытные программисты при выделении памяти используют более консервативный метод: задают выполнение проверки значения возвращенного оператором new указателя, и он начинает использоваться, только если это значение не NULL. В противном случае выделить память не удается, и программа должна как-то отреагировать на это. В результате получается следующее:

int *ptr = new int[BLOCK_SIZE];
if (ptr)
{
  //Память выделена успешно, можно ее использовать
  delete[] ptr; }
else {
  //Выделить память не удалось, примите соответствующие меры 
}

    Прогнозирование потенциальных ошибок и реализация соответствующих процедур увеличивает надежности программы, повышает стабильность ее работы в неблагоприятных условиях, что в свою очередь уменьшает количество сбоев. Программу считают отказоустойчивой (fault-tolerant), если она работает без сбоев, так как способна обрабатывать ошибки. Такой подход с упреждением возможных ошибок можно назвать строчной обработкой ошибок (inline error handling), так как ошибки обрабатываются в месте их возникновения.

    Однако постоянная проверка возвращаемых значений делает программу сложной для чтения и поддержки, так как нарушается ее логическая структура. При этом возникает множество вложенных блоков IF-ELSE, в которых блок IF содержит исполняемый код, а в блоке ELSE обрабатываются ошибки. Следующий пример показывает, как вложенные блоки смещаются вправо, усложняя отслеживание действий программы (особенно, если в ней содержатся длинные строки кода):

if (condition1 == TRUE) 
{
  //Вычисление condition2 
  if (condition2 == TRUE) 
  {
    //Вычисление condition3 
    if (condition3 == TRUE) 
    {
      //Остальные вложенные условия
       .   .   .   
    }
    else
    {
      //Обработка ошибки для condition3
    } 
  }
  else 
  {
    //Обработка ошибки для condition2
  }
} 
else
{
  //Обработка ошибки для condition1
}

    В Microsoft Windows и Visual C++ есть еще один способ строковой обработки ошибок - обработка исключений (exception handling). При этом код разделяется на две части: одна - для нормального выполнения программы, другая - для перехвата ошибок. Код первой секции не проверяет возвращаемые значения и выполняется, как будто никаких ошибок не существует. Код же второй секции перехватывает ошибки по мере их появления.

    На следующем шаге мы рассмотрим исключения.




Предыдущий шаг Содержание Следующий шаг