Я изучал учебники OpenCV и наткнулся на функцию assert
; что он делает?
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
, как правило, с помощью компилятора. Следствием этого является то, что ваша программа никогда не должна полагаться на макрос assert.
// BAD
assert(x++);
// GOOD
assert(x);
x++;
// Watch out! Depends on the function:
assert(foo());
// Here a safer way:
int ret = foo();
assert(ret);
Из комбинации вызова программы abort() и не гарантируется что-либо сделать, утверждения должны использоваться только для проверки того, что разработчик предположил, а не, например, пользователя, вводящего число, а не буквы ( которые должны обрабатываться другими средствами).
assert
обычно вызывает исключение» - в C ++ оно не вызывает «исключение», которое вызывает abort ... оно немного отличается.
#
не вводит комментарий.
Оператор компьютера assert аналогичен выражению , убедитесь, что на английском языке.
Взгляните на
Пример программы assert() в С++
Многие компиляторы предлагают assert() макро. Макрос assert() возвращает TRUE если его параметр оценивает TRUE и принимает какое-то действие, если оно оценивает FALSE. Многие компиляторы будут прервать программу на assert(), который терпит неудачу; другие будут генерировать исключение
Одна мощная функция assert() макрос заключается в том, что препроцессор вообще не сбрасывает код, если 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() может диагностировать ошибки программы. Он определен в ASSERT.H, а его прототип
void assert (int expression); Выражение аргумента может быть любым, что вы хотите проверить - переменной или любым выражением C. Если выражение принимает значение TRUE, assert() ничего не делает. Если выражение принимает значение FALSE, assert() выводит сообщение об ошибке на stderr и прерывает выполнение программы.
Как вы используете assert()?. Он чаще всего используется для отслеживания ошибок программы (которые отличаются от ошибок компиляции). Ошибка не препятствует компиляции программы, но она заставляет ее давать неправильные результаты или запускаться неправильно (например, блокирование). Например, программа финансового анализа, которую вы пишете, может иногда давать неверные ответы. Вы подозреваете, что проблема вызвана переменной interest_rate, принимающей отрицательное значение, чего никогда не должно было случиться. Чтобы проверить это, поместите оператор
assert (interest_rate >= 0); в местах в программе, где используется процент_трассы. Если переменная когда-либо становится отрицательной, макрос assert() предупреждает вас. Затем вы можете изучить соответствующий код, чтобы найти причину проблемы.
Чтобы узнать, как работает assert(), запустите пример программы ниже. Если вы вводите ненулевое значение, программа отображает значение и обычно заканчивается. Если вы вводите нуль, макрос assert() выдает ненормальное завершение программы. Точное сообщение об ошибке, которое вы видите, будет зависеть от вашего компилятора, но здесь типичный пример:
Утверждение не выполнено: x, файл list19_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, существуют ли утверждения, которые действительно вызывают исключения?)
Здесь интересное, немного другое значение assert, используемое c6x и другими компиляторами TI: при просмотре определенных утверждений assert эти компиляторы используют информацию в этом выражении для выполнения определенных оптимизаций. Злая.
Пример в 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-битным границам, поэтому компилятор может генерировать конкретные инструкции для такого выравнивания.
Assert позволяет остановить выполнение, если условие (утверждение) ложно.
Например (псевдокод):
Bank myBank = Bank.GetMyStuff();
assert(myBank != NULL);
// .. Continue.
Если myBank равен NULL, функция прекратит выполнение и возникнет ошибка. Это очень хорошо для того, чтобы сделать код многократного использования приемлемыми условиями и т.д.
abort()
не просто вернется из функции.
С++ 11 Стандартная черновая версия N3337
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
19.3 Утверждения
1 Заголовок <cassert> , описанный в (Таблица 42), предоставляет макрос для документирования утверждений программы на С++ и механизм отключения проверки подтверждения.
2 Содержимое совпадает с заголовком библиотеки Standard C < assert.h > .
C99 N1256 стандартная черта
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
7.2 Диагностика < assert.h >
1 Заголовок
<assert.h>
определяет макрос assert и ссылается на другой макросNDEBUG
, который не определен<assert.h>
. ЕслиNDEBUG
определяется как имя макроса на в исходном файле, где включен < assert.h > , макрос assert определяется просто как#define assert(ignore) ((void)0)
Макрос утверждения переопределяется в соответствии с текущим состоянием NDEBUG каждый раз, когда
<assert.h>
.2. Макрос утверждения должен быть реализован как макрос, а не как фактическая функция. Если определение макроса подавляется для доступа к фактической функции, поведение undefined.
7.2.1 Диагностика программы
7.2.1.1 Утверждающий макрос
Сводка
1.
#include <assert.h> void assert(scalar expression);
Описание
2 Макрос утверждений ставит диагностические тесты в программы; он расширяется до выражения void. Когда он выполняется, если выражение (которое должно иметь скалярный тип) является ложным (то есть, сравнивается с 0), макрос assert записывает информацию о конкретном вызове, который (включая текст аргумента, имя исходного файла, исходную строку номер и имя прилагаемой функции - последние являются соответственно значениями макросы предварительной обработки
__FILE__
и__LINE__
и идентификатора__func__
) в стандартном потоке ошибок в формате, определяемом реализацией. 165) Это затем вызывает функцию прерывания.Возвращает
3 Макрос assert не возвращает значение.
Это функция, которая остановит выполнение программы, если значение, которое оно оценило, является ложным. Обычно он окружен макросом, так что он не компилируется в результирующий двоичный файл при компиляции с настройками выпуска.
Он предназначен для тестирования допущений, которые вы сделали. Например:
void strcpy(char* dest, char* src){
//pointers shouldn't be null
assert(dest!=null);
assert(src!=null);
//copy string
while(*dest++ = *src++);
}
Идеальным, который вы хотите, является то, что вы можете сделать ошибку в своей программе, например, вызвать функцию с недопустимыми аргументами, и вы нажмете assert перед тем, как он segfaults (или не работает должным образом)
Кроме того, вы можете использовать его для проверки успешного выполнения динамического размещения.
Пример кода:
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
- зло.