Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
PR_СП_лабы_11.doc
Скачиваний:
7
Добавлен:
22.04.2019
Размер:
755.71 Кб
Скачать

4. Макрос 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");

Поради щодо використання assert ().

1. Перевірки наявності порожніх покажчиків, наприклад, в списку аргументів функції. Повідомлення про помилку, що генерується рядком

{ assert (pointer! = NULL)}

Отримане повідомлення про помилку

Assertion 'pointer! = (Void *)O)'failed

більш інформативно, ніж повідомлення, що видається у відповідь на спробу розкриття порожнього покажчика:

Segmentation fault ( core dumped)

2. Перевіряйте значення параметрів функції. Наприклад, якщо у функції передбачається, що параметр foo має тільки позитивні значення, поставте наступну перевірку на самому початку тіла функції:

assert (foo> 0);

Це допоможе виявити випадки неправильного використання функції, а також дасть зрозуміти кожному, хто переглядає вихідний текст програми , що функція накладає обмеження на значення параметра.

3. Макрос assert () не слід застосовувати для перевірки даних, що вводяться користувачем. Звичайно, вхідні дані завжди потрібно перевіряти, але іншими способами. Макрос assert () призначений лише для внутрішніх перевірок.

Приклад

# include <assert.h>

# include <stdio.h>

char * string = "" / * порожній рядок * /

int value = 1;

main ()

{assert(value> 0);

printf ("Пройшли assert ( value> 0) \ n ");

assert (* string! = '0');}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]