Функция assert(). Отлов ошибок и вывод их на экран (С++)
Содержание
Intro
Часть времени кодеры обязательно посвящают отлову багов (=ошибок), которые так любят крашить программы.1
По дебагингу (=отладке) написана не одна сотня книг. Но в чистом виде (низкоуровневый) дебагинг - своя, довольно обширная "кухня", освоить которую весьма непросто. Кроме того, в Express редакциях MSVC++ отладчик вырезан напрочь (ограничение бесплатной версии). Поэтому для отлова ошибок воспользуемся замечательной функцией assert().
Типичные ошибки
Типичными ошибками являются:
- необъявленные переменные;
- некорректные значения;
- использование неинициализированных указателей (uninitialized pointers).
Также частой ошибкой является присвоение переменным похожих имён:
char *MyName; char *MyNames;
Простое добавление одной буквы s к имени второй переменной в изрядно разросшемся коде может вызвать путаницу. Поэтому по возможности избегай похожих имён.
Применение функции assert()
Игрокодеры применяют Функцию assert() для отслеживания некорректных (incorrect) значений и непроинициализированных указателей. Суть функции assert() заключается в проверке выражения на истинность. Когда такая проверка возвращает значение FALSE, (в случае оконного приложения) выскакивает всплывающее окно (Popup window) с сообщением об ошибке и приложение завершает работу (aborts).
Разместив вызов функции assert() в определённых участках кода, можно легко проверить, что значение переменной выбрано корректно или указать проинициализирован. Если это не так, то в сообщении об ошибке будет содержаться подробная информация о файле исходного кода и номере строки, где данная ошибка возникла.
Рассмотрим пример:
// Подключаем заголовок assert.h #include <assert.h> // Объявляем переменную и указатель, которые надо отследить. long dwValue = 10; char *pPtr = NULL; // Проверяем, присвоено ли переменной значение 20. assert(dwValue == 20); // Выдаст ошибку. // Проверяем указатель на NULL-значение assert(pPtr != NULL); // Выдаст ошибку. ...
Здесь обе проверки вызовут сообщение об ошибке, т.к. указатель NULL, а значение объявленной переменной - вовсе не 20.
Отключение вызова функции assert()
Самое замечательное в этой функции то, что в случае ненадобности все её вызовы можно просто запретить путём вызова специальной директивы компилятора. Это избавит кодера от необходимости рыскать по коду в поисках ранее её установленных вызовов. Достаточно разместить в начале листинга строку:
#define NDEBUG ... #include <assert.h> ...
Да, наличие ссылки #include <assert.h> при этом также необходимо!
Заключение
Технически сообщения об ошибках появляются путём вызова функции MessageBox. Функция assert() не возвращает значение.
Jim Adams в своей книге "Programming Role Playing Games with DirectX 8.0" пишет, что часто использует функцию assert() просто для вывода значений нужных ему переменных на разных этапах выполнения программы. В этом случае каждый вызов assert() является своеобразным брейкпоинтом (=breakpoint, точка останова). Применять или нет функцию assert() - решать тебе. Но знать о её существовании и уметь с ней работать необходимо.
Последние комментарии