Книга: Программист-прагматик. Путь от подмастерья к мастеру
Не отключайте утверждения
Разделы на этой странице:
Не отключайте утверждения
Существует расхожее недопонимание утверждений, которое провозгласили те, кто разрабатывает компиляторы и языковые среды. Оно формулируется примерно так:
«Утверждения являются лишним бременем для программы. Поскольку они проверяют то, что никогда не должно случиться, их действие инициируется только ошибкой в тексте программы. Как только программа проверена и отправлена заказчику, необходимость в них отпадает и их надо отключить для ускорения работы программы. Утверждения нужны лишь во время отладки» .
В этом высказывании имеется два явно неправильных предположения. Первое – авторы высказывания полагают, что при тестировании обнаруживаются все ошибки. В действительности маловероятно, что процедура тестирования любой сложной программы всегда будет происходить по единому сценарию, даже при минимальном проценте перестановок в тексте программы (см. «Безжалостное тестирование»). Второе – эти оптимисты забывают, что ваша программа выполняется в опасном мире. Весьма вероятно, что во время тестирования крысы не будут прогрызать кабели, никто не будет забивать память, запуская игрушку, а файлы журналов не переполнят жесткий диск. Все это может происходить, если ваша программа выполняется в реальных условиях. Ваш первый оборонительный рубеж – проверка наличия любой вероятной ошибки, а второй – использование утверждений для обнаружения тех ошибок, которые прошли первый рубеж.
Отключение утверждений при доставке программы заказчику сродни хождению по канату без страховочной сетки на том основании, что когда-то вы уже так делали. Сумма страховки велика, но получить ее в случае падения довольно сложно.
Даже при наличии некоторых проблем с производительностью, отключите только те утверждения, которые действительно оказывают серьезное воздействие. Пример с программой сортировки, представленный выше, может быть самой важной частью вашего приложения и, наверное, должен работать быстро. Добавление процедуры проверки означает новое считывание данных, что может быть неприемлемо. Сделайте эту конкретную процедуру проверки необязательной [26], но оставьте в покое все остальные.
Утверждения и побочные эффекты
Становится как-то неловко, если программа, добавляемая для обнаружения ошибок, в результате создает новые. Это может происходить с утверждениями в том случае, если вычисление условия имеет побочные эффекты. Например, было бы дурным тоном написать на языке Java нечто вроде:
while (iter.hasMoreElements() {
Test.ASSERT(iter.nextElement() != null);
Object obj = iter.nextElement();
// ...
}
Вызов .nextElement() в ASSERT обладает побочным эффектом, заключающимся в перемещении указателя цикла за выбираемый элемент, так что цикл обрабатывает лишь половину элементов совокупности. Лучше было бы записать:
while (iter.hasMoreElements()) {
Object obj = iter.nextElement();
Test.ASSERT(obj != null);
//…
}
Эта проблема являются разновидностью так называемого «Heisen-bug» – процесса отладки, изменяющего поведение отлаживаемой системы (см. [URL 52]).
Другие разделы, относящиеся к данной теме:
• Отладка
• Проектирование по контракту
• Балансировка ресурсов
• Программирование в расчете на совпадение
Упражнения
19. Быстрый тест на ощущение реальности. Какие из перечисленных «невозможных» событий могут случаться в реальности? (Ответ см. в Приложении В.)
1. Месяц, количество дней в котором меньше 28
2. Stat(».»,&sb)== –1 (т. е. невозможно обращение к текущему каталогу)
3. В языке С++: а = 2; b = 3; if (а + b != 5) exit(1);
4. Треугольник, сумма величин внутренних углов которого не равна 180°
5. Минута, состоящая не из 60 секунд
6. В языке Java: (а + 1) <= а
20. Разработайте несложный класс Java для проверки утверждений (Ответ см. в Приложении В.)
- Инструкция утверждения
- Утверждения как средство для написания корректного ПО
- IV. Рисунки для утверждения планов
- Утверждения
- Утверждения (Assertions)
- Утверждения не являются механизмом проверки вводимых данных
- Утверждения это не управляющие структуры
- Работа с утверждениями
- Включение функций в утверждения
- У11.3 Полные утверждения для стеков
- У11.6 Утверждения и экспорт
- Переопределение и утверждения