Урок №115. assert і static_assert

  Юрій  | 

  Оновл. 23 Січ 2021  | 

 59

Використання операторів умовного розгалуження для виявлення помилкового припущення, а також для виведення повідомлень про помилки і завершення виконання програми є настільки поширеним рішенням виникаючих проблем, що C++ вирішив цю справу спростити. І спростив він її за допомогою assert.

Стейтмент assert

Стейтмент assert (або “оператор перевіркового твердження”) в мові C++ — це макрос препроцесора, який обробляє умовний вираз під час виконання. Якщо умовний вираз істинний, то стейтмент assert нічого не робить. Якщо ж умовний вираз помилковий, то виводиться повідомлення про помилку, і виконання програми завершується. Повідомлення про помилку містить помилковий умовний вираз, а також ім’я файлу з кодом і номером рядка з assert. Таким чином, можна легко знайти та ідентифікувати проблему, що дуже допомагає при відлагодженні програм.

Сам assert реалізований в заголовку cassert і часто використовується як для перевірки коректності переданих параметрів функції, так і для перевірки значення, що повертається:

Якщо у вищенаведеній програмі викликати getArrayValue(array, -3);, то програма виведе наступне повідомлення:

Assertion failed: index >= 0 && index <=8, file C:\\VCProjects\\Program.cpp, line 6

Рекомендується використовувати стейтменти assert. Іноді твердження assert бувають не надто описовими, наприклад:

Якщо цей assert спрацює, то ми отримаємо:

Assertion failed: found, file C:\\VCProjects\\Program.cpp, line 42

Але про що це нам говорить? Очевидно, що щось не було знайдено, але що саме? Вам потрібно буде самому пройтися по коду, щоб це визначити.

На щастя, є невеликий трюк, який можна використати для виправлення цієї ситуації. Просто додайте повідомлення в якості рядка C-style разом з логічним оператором І:

Як це працює? Рядок C-style завжди приймає значення true. Тому, якщо found прийме значення false, то false && true = false. Якщо ж found прийме значення true, то true && true = true. Таким чином, рядок C-style взагалі не впливає на обробку твердження.

Проте, якщо assert спрацює, рядок C-style буде включений в повідомлення assert:

Assertion failed: found && "Animal could not be found in database", file C:\\VCProjects\\Program.cpp, line 42

Це дасть додаткове пояснення того, що пішло не так.

NDEBUG

Функція assert() витрачає мало ресурсів на перевірку умови. Крім того, стейтменти assert (в ідеалі) ніколи не повинні зустрічатися в релізному коді (бо ваш код до цього моменту вже повинен бути ретельно протестований). Відповідно, деякі розробники вважають за краще використовувати assert тільки в конфігурації Debug. У мові C++ є можливість відключити всі assert-и в релізному коді, для цього потрібно використати директиву #define NDEBUG:

Деякі IDE встановлюють NDEBUG за замовчуванням, як частину параметрів проекту в конфігурації Release.

Зверніть увагу, функція exit() і assert (якщо він спрацьовує) негайно припиняють виконання програми, без можливості виконати подальшу будь-яку очистку (наприклад, закрити файл або базу даних). Через це їх слід використовувати акуратно.

static_assert

У C++11 додали ще один тип assert-а — static_assert. На відміну від assert, який спрацьовує під час виконання програми, static_assert спрацьовує під час компіляції, викликаючи помилку компілятора, якщо умова не є істинною. Якщо умова помилкова, то виводиться діагностичне повідомлення.

Ось приклад використання static_assert для перевірки розмірів певних типів даних:

Результат на моєму комп’ютері:

1>C:\ConsoleApplication1\main.cpp(19): error C2338: long must be 8 bytes

Оскільки static_assert обробляється компілятором, то умовна частина static_assert також повинна оброблятися під час компіляції. Оскільки static_assert не обробляється під час виконання програми, то стейтменти static_assert можуть бути розміщені в будь-якому місці коду (навіть в глобальному просторі).

У C++11 діагностичне повідомлення повинно бути обов’язково надано в якості другого параметра. У C++17 надання діагностичного повідомлення є необов’язковим.

Оцінити статтю:

1 Зірка2 Зірки3 Зірки4 Зірки5 Зірок (2 оцінок, середня: 5,00 з 5)
Loading...

Залишити відповідь

Ваш E-mail не буде опублікований. Обов'язкові поля відмічені *