Я вивчав уроки OpenCV і натрапив на assert
функцію; що воно робить?
Я вивчав уроки OpenCV і натрапив на assert
функцію; що воно робить?
Відповіді:
assert
завершить програму (як правило, повідомленням, що цитує твердження твердження), якщо її аргумент виявиться помилковим. Він зазвичай використовується під час налагодження, щоб зробити програму більш очевидною, якщо виникає несподівана умова.
Наприклад:
assert(length >= 0); // die if length is negative.
Ви також можете додати більш інформативне повідомлення, яке відображатиметься, якщо воно не вдається таким чином:
assert(length >= 0 && "Whoops, length can't possibly be negative! (didn't we just check 10 lines ago?) Tell jsmith");
Або ще так:
assert(("Length can't possibly be negative! Tell jsmith", length >= 0));
Коли ви робите збірку (не налагодження), ви також можете видалити накладні оцінки assert
операторів, визначивши NDEBUG
макрос, як правило, за допомогою компілятора компілятора. Наслідком цього є те, що ваша програма ніколи не повинна покладатися на запущений макрос затвердження.
// BAD
assert(x++);
// GOOD
assert(x);
x++;
// Watch out! Depends on the function:
assert(foo());
// Here's a safer way:
int ret = foo();
assert(ret);
З поєднання програми, яка викликає abort () і не гарантується нічого робити, твердження повинні використовуватися лише для тестування речей, які припустив розробник, а не, наприклад, користувача, який вводить число, а не літеру (яка повинна бути обробляється іншими способами).
assert
зазвичай викликає виняток" - у C ++ він не збільшується "виняток", він називає аборт ... він трохи інший.
#
символ не вводить коментар.
assert("error message", expression)
Стверджують , комп'ютер твердження аналогічно висловом переконайтеся , що на англійській мові.
Подивись на
Приклад програми assert () в C ++
Багато компіляторів пропонують макрос assert (). Макрос assert () повертає TRUE, якщо його параметр оцінює TRUE та виконує якусь дію, якщо він оцінює FALSE. Багато компіляторів скасують програму, якщо не вдасться; інші кинуть виняток
Однією з потужних особливостей макросу assrt () є те, що препроцесор згортає його взагалі без коду, якщо DEBUG не визначений. Це чудова допомога під час розробки, і коли кінцевий продукт поставляється, не передбачено штрафної продуктивності, а також збільшення розміру виконуваної версії програми.
Напр
#include <stdio.h>
#include <assert.h>
void analyze (char *, int);
int main(void)
{
char *string = "ABC";
int length = 3;
analyze(string, length);
printf("The string %s is not null or empty, "
"and has length %d \n", string, length);
}
void analyze(char *string, int length)
{
assert(string != NULL); /* cannot be NULL */
assert(*string != '\0'); /* cannot be empty */
assert(length > 0); /* must be positive */
}
/**************** Output should be similar to ******************
The string ABC is not null or empty, and has length 3
Функція assert () може діагностувати програмні помилки. У C він визначений у <assert.h>
, а в C ++ - у <cassert>
. Її прототип є
void assert(int expression);
Вираз аргументу може бути будь-яким, що ви хочете перевірити - змінним або будь-яким виразом C. Якщо вираз оцінюється як ІСТИНА, assert () нічого не робить. Якщо вираз оцінюється на FALSE, assrt () відображає повідомлення про помилку при виконанні програми stderr і перериває виконання програми.
Як ви використовуєте assert ()? Він найчастіше використовується для відстеження програмних помилок (які відрізняються від помилок компіляції). Помилка не заважає програмі компілювати програму, але вона призводить до неправильних результатів або неправильного запуску (наприклад, блокування). Наприклад, програма фінансового аналізу, яку ви пишете, може періодично давати неправильні відповіді. Ви підозрюєте, що проблема викликана тим, що змінна interest_rate приймає негативне значення, що ніколи не повинно відбуватися. Щоб перевірити це, поставте заяву
assert (interest_rate> = 0); у місцях програми, де використовується interest_rate. Якщо змінна коли-небудь стає негативною, макрос assert () попереджає вас. Потім ви можете вивчити відповідний код, щоб виявити причину проблеми.
Щоб побачити, як працює assrt (), запустіть зразок програми нижче . Якщо ви введете ненульове значення, програма відображає це значення і нормально припиняється. Якщо ви введете нуль, макрос assrt () примушує ненормальне завершення програми. Точне повідомлення про помилку, яке ви побачите, залежатиме від вашого компілятора, але ось типовий приклад:
Не вдалося стверджувати: x, список файлів19_3.c, рядок 13 Зверніть увагу, що для того, щоб assert () працював, ваша програма повинна бути скомпільована в режимі налагодження. Інформацію про включення режиму налагодження (як це пояснено за мить) див. У документації на компілятор. Коли ви згодом компілюєте остаточну версію в режимі випуску, макроси assert () відключаються.
int x;
printf("\nEnter an integer value: ");
scanf("%d", &x);
assert(x >= 0);
printf("You entered %d.\n", x);
return(0);
Введіть ціле значення: 10
Ви ввели 10.
Введіть ціле значення: -1
Повідомлення про помилку: ненормальне завершення програми
Ваше повідомлення про помилку може відрізнятися залежно від вашої системи та компілятора, але загальна ідея та ж.
Такі речі, як "підвищує виняток" та "зупиняє виконання", може бути правдою для більшості компіляторів, але не для всіх. (BTW, чи є твердження твердження, що насправді кидають винятки?)
Ось цікавий, дещо інший сенс затвердження, що використовується c6x та іншими компіляторами TI: побачивши певні заяви твердження, ці компілятори використовують інформацію в цьому операторі для здійснення певних оптимізацій. Злий.
Приклад в C:
int dot_product(short *x, short *y, short z)
{
int sum = 0
int i;
assert( ( (int)(x) & 0x3 ) == 0 );
assert( ( (int)(y) & 0x3 ) == 0 );
for( i = 0 ; i < z ; ++i )
sum += x[ i ] * y[ i ];
return sum;
}
Це повідомляє де компілятору масиви вирівнюються за 32-бітовими межами, тому компілятор може генерувати конкретні інструкції, зроблені для такого вирівнювання.
C ++ 11 стандартна тяга N3337
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
19.3 твердження
1 Заголовок <cassert>, описаний у (табл. 42), містить макрос для документування тверджень програми C ++ та механізм відключення перевірок твердження.
2 Вміст такий самий, як у заголовку бібліотеки Standard C <assert.h>.
C99 N1256 стандартна тяга
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
7.2 Діагностика <assrt.h>
1 Заголовок
<assert.h>
визначає макрос затвердження і посилається на інший макрос,NDEBUG
який не визначений<assert.h>
. ЯкщоNDEBUG
визначено як ім'я макросу в точці вихідного файлу, куди включено <assrt.h>, макрос assert визначається просто як#define assert(ignore) ((void)0)
Макрос затвердження перевизначається відповідно до поточного стану NDEBUG кожного разу, коли
<assert.h>
він включається.2. Макрос затвердження повинен бути реалізований як макрос, а не як фактична функція. Якщо визначення макросу придушено для доступу до фактичної функції, поведінка не визначена.
7.2.1 Програма діагностики
7.2.1.1 Макрос затвердження
Конспект
1.
#include <assert.h> void assert(scalar expression);
Опис
2 Макроствердження встановлює діагностичні тести в програми; воно розширюється до порожнечого виразу. Коли він виконується, якщо вираз (який має скалярний тип) є помилковим (тобто порівнюється рівним 0), макрос затвердження записує інформацію про конкретний виклик, який не вдався (включаючи текст аргументу, ім'я вихідний файл, номер рядка джерела та назва функції, що додає - останні відповідно значень макросів попередньої обробки
__FILE__
та__LINE__
ідентифікатора__func__
) у стандартному потоці помилок у форматі, визначеному реалізацією. 165) Потім він викликає функцію переривання.Повертається
3 Макрос затвердження не повертає значення.
Існує три основні причини використання функції assrt () над звичайною, якщо інше і printf
Функція assert () використовується, головним чином, на етапі налагодження, втомливо писати, якщо інше із заявою printf кожен раз, коли ви хочете перевірити умову, яка може навіть не пробитися у кінцевому коді.
У великих розгортаннях програмного забезпечення asrt стає дуже зручним, коли ви можете змусити компілятор ігнорувати заяви заяви, використовуючи макрос NDEBUG, визначений перед тим, як зв’язати файл заголовка для функції assert ().
assert () стане в нагоді, коли ви розробляєте функцію або якийсь код і хочете отримати уявлення про те, що обмежує код, а не працює, і, нарешті, включіть, якщо інше, для його оцінки, в основному, граючи з припущеннями.
Це функція, яка зупинить виконання програми, якщо значення, яке вона оцінила, помилкове. Зазвичай він оточений макросом, щоб він не компілювався в результуючий бінарний файл при компіляції з налаштуваннями випуску.
Він призначений для використання для перевірки зроблених вами припущень. Наприклад:
void strcpy(char* dest, char* src){
//pointers shouldn't be null
assert(dest!=null);
assert(src!=null);
//copy string
while(*dest++ = *src++);
}
Ідеальний варіант, який ви хочете, - це ви можете помилитися у вашій програмі, наприклад, викликати функцію з недійсними аргументами, і ви натискаєте на затвердження, перш ніж вона не буде працювати (або не спрацьовує, як очікувалося)
Крім того, ви можете використовувати його, щоб перевірити, чи був динамічний розподіл успішним.
Приклад коду:
int ** p;
p = new int * [5]; // Dynamic array (size 5) of pointers to int
for (int i = 0; i < 5; ++i) {
p[i] = new int[3]; // Each i(ptr) is now pointing to a dynamic
// array (size 3) of actual int values
}
assert (p); // Check the dynamic allocation.
Схожий на:
if (p == NULL) {
cout << "dynamic allocation failed" << endl;
exit(1);
}
new
Викидає виняток при відмові розподілу, якщо не вказати nothrow
(чого ви тут не вказали ). Крім того, ваше форматування є дивним і exit
злим.
assert()
тільки для налагодження і викорінення речі , які ніколи, ніколи НЕ повинні ніколи трапитися - задовго до того, як побудувати реліз.