ЛЕКЦИЯ 30 Тема 3.8 Защитное программирование 1. Способы проявления ошибок. 2. Принципы защитного программирования. 3. Рекомендации по защитному программированию. 1. Способы проявления ошибок Любая из ошибок программирования, которая не обнаруживается на этапах компиляции и компоновки программ, в конечном счете может проявиться тремя способами: привести к выдаче системного сообщения об ошибке, «зависанию» компьютера и получению неверных результатов. Ошибки определения исходных Ошибки проектирования Ошибки кодирования Ошибки накопления погрешностей данных Системное сообщение об ошибке Неверные промежуточные результаты Неверные управляющие переменные Неверные типы данных Неверные индексы массивов Неверные параметры циклов Другие «Зависание «компьютера Неверные результаты Рисунок 1 - Способы проявления ошибок Однако до того как результат работы программы становится фатальным, ошибки обычно много раз проявляются в виде неверных промежуточных результатов, неверных управляющих переменных, неверных типах данных, индексах структур данных и т.д. (рисунок 3.1). А это значит, что часть ошибок можно попытаться обнаружить и нейтрализовать, пока они еще не привели к тяжелым последствиям. Для этого используется защитное программирование. При его использовании существенно уменьшается вероятность получения неверных результатов. Защитное программирование – это такой стиль написания программ, при котором появляющиеся ошибки легко обнаруживаются и идентифицируются программистом. Детальный анализ ошибок и их возможных ранних проявлений показывает, что целесообразно проверять: правильность выполнения операций ввода-вывода; допустимость промежуточных результатов (значений управляющих переменных, значений индексов, типов данных, значений числовых аргументов и т.д.). Проверка правильности операций ввода-вывода. Причины неверного определения исходных данных: внутренние ошибки – ошибки устройств ввода-вывода или программного обеспечения; внешние ошибки – ошибки пользователя. Различают: ошибки передачи (аппаратные средства, например, вследствие неисправности, искажают данные); ошибки преобразования (программа неверно преобразует исходные данные из входного формата во внутренний); ошибки перезаписи (пользователь ошибается при вводе данных, например, вводит лишний или другой символ); ошибки данных (пользователь вводит неверные данные). Ошибки передачи обычно контролируются аппаратно. Для защиты от ошибок преобразования данные после ввода обычно сразу демонстрируют пользователю. При этом выполняют сначала преобразование во внутренний формат, а затем обратно. Предотвратить все ошибки на данном этапе сложно, поэтому соответствующие фрагменты программы тщательно тестируют. Обнаружить и устранить ошибки перезаписи можно только, если пользователь вводит избыточные данные, например контрольные суммы. Если ввод избыточных данных нежелателен, то следует проверять вводимые данные, хотя бы контролировать интервалы возможных значений, которые обычно определены в техническом задании, и выводить введенные данные для проверки пользователю. Неверные данные может обнаружить только пользователь. Проверка допустимости промежуточных результатов. Эта проверка позволяет снизить вероятность позднего проявления не только ошибок неверного определения данных, но и некоторых ошибок кодирования и проектирования. Для этого используют в программе переменные, для которых существуют ограничения, например, связанные с сущность моделируемых процессов. Предотвращение накопления погрешностей. Чтобы снизить погрешность результатов вычислений, необходимо соблюдать следующие рекомендации: избегать вычитания близких чисел (машинный ноль); избегать деления больших чисел на малые; сложение длинной последовательности чисел начинать с меньших по абсолютной величине; стремиться по возможности уменьшать количество операций; использовать методы с известными оценками погрешностей; не использовать условие равенства вещественных чисел; вычисления производить с двойной точность, а результат выдавать – с одинарной. Обработка исключений. Поскольку полный контроль данных на входе и в процессе вычислений не возможен, следует предусмотреть перехват обработки аварийных ситуаций. Для перехвата и обработки аппаратно и программно фиксируемых ошибок в некоторых языках программирования предусмотрены средства обработки исключений. Использование их позволяет пользователю не допустить выдачи пользователю сообщения об аварийном завершении программы, ничего ему не говорящего. Вместо этого программист получает возможность предусмотреть действия, которые позволят исправить эту ошибку или выдать пользователю сообщение с точным описанием ситуации и продолжить работу. 2. Принципы защитного программирования Существуют три основных принципа защитного программирования: 1. Общее недоверие. Для каждого модуля входные данные должны тщательно анализироваться в предположении, что они могут быть ошибочными. 2. Немедленное обнаружение. Каждая ошибка должна быть выявлена как можно раньше, это упрощает установление ее причины. 3. Изолирование ошибки. Ошибки в одном модуле должны быть изолированы так, чтобы не допустить их влияние на другие модули. 3. Рекомендации по защитному программированию Рекомендации по защитному программированию: Делайте проверку области значений переменных. Выполняйте контроль правдоподобности значений переменных, которые не должны превышать некоторых констант или значений других переменных Контролируйте итоги вычислений. Включайте автоматические проверки (например, контроль переполнения или потери точности). Проверяйте длину элементов информации. Проверяйте коды возврата функций.