Загрузка...
 
Печать

Функция 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(external link), точка останова). Применять или нет функцию assert() - решать тебе. Но знать о её существовании и уметь с ней работать необходимо.

Источники:


1. Jim Adams. Programming Role Playing Games with DirectX 8.0. - Premier Press. 2002

Contributors to this page: slymentat .
Последнее изменение страницы Понедельник 30 / Ноябрь, 2020 03:10:06 MSK автор slymentat.

Помочь проекту

Яндекс-деньги: 410011791055108