Макрос asssert()
Розроблено методики програмування, що дозволяють виявляти помилки на ранніх стадіях і вирішувати проблеми, що виникають у ході виконання програми.
Найпростіший спосіб виявлення ненормальних ситуацій - стандартний макрос asssert() у мові С.
# Include <assert.h>
assert (expression, [error_string])
Його аргументом є логічне вираження.
Якщо
expression = TRUE програма триває
Якщо
expression = FALSE програма завершується і видає повідомлення про помилку з зазначенням вихідного файлу, номер рядка, а також тексту вираження, що призвів до помилки. При цьому розробнику надається вибір - остаточно перервати роботу програми (Abort), перемкнутися в вікно отладчика (Retry) або продовжити роботу (Ignore).
Assert реалізований як макрос, тому вираз expression не може містити текстових літералів.
Даний макрос корисний для включення діагностики у програми:
− правильність аргументів функцій,
− виконання вхідних і вихідних умов при виклику функцій.
− наявність непередбачених повертаються значень.
Assert() зручний ще тим, що є документацією, яка описує роботу програми безпосередньо в її початковому тексті. Якщо програма містить рядок assert (умова), то будь-який, хто читає вихідний текст, буде знати, що в даній точці програми зазначена умова завжди повинно бути істинним. Якщо ж умова не виконується, то, очевидно, в програмі присутня помилка.
Макрос ASSERT відстежує програмні помилки лише в перевіреній версії програми (#define DEBUG - стоїть за умовчанням). Цей макрос не створює ніякого коду в остаточній версії. Якщо саме в остаточній версії потрібно оцінити вираз, замість ASSERT слід застосовувати макрос VERIFY.
Якщо програма компілюється як реліз (# define NDEBUG), препроцесор прибирає з тіла програми всі виклики макросу assert (). Це має сенс тільки тоді, коли продуктивність є вузьким місцем програми, причому макрос потрібно відключати лише в найбільш критичних файлах.
Визначення ndebug повинно бути перед включенням файлу assert.h, тоді оператори assert () будуть "закоментовані".
Оскільки макрос assert () може віддалятися препроцесором з програми, потрібно ретельно перевірити, чи не мають вираження з ним побічних ефектів. У них не слід викликати функції, присвоювати значення змінним і користуватися модифікуючими операторами типу + +.
Наприклад, нехай у циклі викликається функція funct (). У разі успішного виконання вона повертає 0, інакше - нульове значення. Якщо написати так:
for (i = 0; i <100; + + i)
assert (funct () == 0);
програма буде зупинятися при успішному виконанні функції.
Припустимо, програма перекомпілювати з макроконстантой NDEBUG. У результаті з програми будуть видалені всі макроси assert (), і функція funct () взагалі не буде викликано. Щоб уникнути цього необхідно використовувати наступний підхід:
for (i = 0; i <100; + + i)
{int status = do_something ();
assert (status ==
0);}
В якості додаткового параметра assert може приймати також повідомлення, яке треба надрукувати в разі спрацювання.
assert (fopen (sFile), "Couldn't open file \ n");