Перейти к содержимому

Assert c что это

  • автор:

assert: функция сообщения об ошибке в С++

Функция assert оценивает выражение, которое передается ей в качестве аргумента, через параметр expression . Если аргумент-выражение этого макроса в функциональной форме равно нулю (т.е. выражение ложно), сообщение записывается на стандартное устройство вывода ошибок и вызывается функция abort , работа программы прекращается.

Содержание сообщения об ошибке зависит от конкретной реализации компилятора, но любое сообщение должно состоять из: выражения, которое assert оценивает, имя файла c ошибкой и номер строки, где произошла ошибка. Обычный формат сообщения об ошибке :

filename: line number: expression: аssertion failed:
#define NDEBUG // в начале файла исходного кода, перед включением заголовочного файла

Параметры:

  • expression
    Выражение для оценки. Если логическое выражение в параметре expression равно 0, функция assert немедленно завершает программу.

Возвращаемое значение

Пример: исходный код программы

// пример использования функции assert #include // для оператора cout #include // для функции assert void print_adds(int* value) < assert(value != NULL); std::cout int main() < int a = 10; int *ptr1 = &a; // указатель на переменную a int *ptr2 = NULL; // нулевой указатель print_adds(ptr1); // вызов функции с ненулевым указателем print_adds(ptr2); // вызов функции с нулевым указателем return 0; >

Пример работы программы

В этом примере, функция assert используется, чтобы прервать выполнение программы, если функции print_adds в качестве аргумента передаётся нулевой указатель. В программе, первый вызов функции print_adds завершается успешно. Второй вызов, в качестве аргумента, принимает нулевой указатель ptr2 . И как раз в этот момент срабатывает функция assert , она оценивает выражение, в данном случае нулевой указатель. Нулевой указатель не указывает ни на какой блок памяти, поэтому assert сигнализирует об ошибке и немедленно завершает работу программы.

CppStudio.com

Адрес значения в памяти = 0x7fff5900f8ac
er: ../er/main.cpp:7: void print_adds(int*): Assertion `value != __null’ failed.

void assert(int exp)

Макрос assert() пишет сообщение об ошибке в stderr и завершает программу в том случае, если выражение ехр равно 0. В противном случае, если ехр не равно 0, макрос assert() не производит никаких действий.

Вывод имеет следующий формат:
Assertion failed: ехр, file , line Макрос assert() обычно используется для проверки корректности работы программы. Нет необходимости удалять инструкцию assert() из исходного кода после отладки программы, поскольку если макрос NDEBUG определен перед включением заголовочного файла assert.h, то макрос assert() игнорируется.

Следующий фрагмент кода используется для тестирования данных , прочитанных с последователь­ного порта в формате ASCII ( это означает , что седьмой разряд не используется ) :
.
ch = read_port ( ) ;
assert ( ! ( ch & 128 ) ) ; /* проверка седьмого бита */
.

assert макрос, _assert , _wassert

Вычисляет выражение и, если результат false , выводит диагностическое сообщение и прерывает выполнение программы.

Синтаксис

assert( expression ); void _assert( char const* message, char const* filename, unsigned line ); void _wassert( wchar_t const* message, wchar_t const* filename, unsigned line ); 

Параметры

expression
Скалярное выражение (включая выражения указателя), которое возвращает ненулевое значение ( true ) или 0 ( false ).

message
Отображаемое сообщение.

filename
Имя файла исходного кода, в котором произошел сбой утверждения.

line
Номер строки в файле исходного кода, в которой произошел сбой утверждения.

Замечания

Макрос assert обычно используется для выявления ошибок логики во время разработки программы. Используйте его для остановки выполнения программы при возникновении непредвиденных условий. Для этого реализуйте аргумент expression так, чтобы он принимал значение false только в том случае, если программа работает неправильно. Проверки утверждения можно отключить во время компиляции, определив макрос NDEBUG . Макрос можно отключить assert без изменения исходных файлов с помощью параметра командной /DNDEBUG строки. Вы можете отключить assert макрос в исходном #define NDEBUG коде с помощью директивы перед включением.

Макрос assert выводит диагностическое сообщение при expression оценке (0) и вызовы false abort для остановки выполнения программы. Если значение expression равно true (отлично от нуля), никаких действий не выполняется. Диагностическое сообщение включает выражение, где произошел сбой, имя файла исходного кода и номер строки, со сбоем утверждения.

Диагностическое сообщение выводится в широких ( wchar_t ) символах. Таким образом, он будет работать должным образом, даже если в выражении есть символы Юникода.

Назначение диагностического сообщения зависит от типа приложения, которое вызвало подпрограмму. Консольные приложения получают сообщение через stderr . В приложении assert под управлением Windows вызывает функцию Windows MessageBox , чтобы создать окно сообщения, чтобы отобразить сообщение с тремя кнопками: Прерывание, повторная попытка и игнорировать. Если пользователь выбирает прерывание, программа прерывается немедленно. Если пользователь выбирает повторную попытку, то вызывается отладчик, и пользователь может отладить программу, если включена JIT-отладка. Если пользователь выберет «Игнорировать», программа продолжит нормальное выполнение. Нажатие кнопки «Игнорировать» , если условие ошибки существует, может привести к неопределенному поведению, так как предварительные условия вызывающего кода не были выполнены.

Чтобы переопределить поведение выходных данных по умолчанию независимо от типа приложения, вызовите _set_error_mode выбор между поведением вывода к stderr и display-dialog-box.

После assert отображения сообщения он вызывает abort диалоговое окно с кнопками «Прерывание«, «Повтор» и «Игнорировать «. abort завершает программу, поэтому кнопка «Повторить» и «Игнорировать« не возобновляет выполнение программы после assert вызова. Если assert отображается диалоговое окно, abort диалоговое окно не отображается. Единственное время отображения диалогового abort окна — при assert отправке выходных данных в stderr.

В результате приведенного выше поведения диалоговое окно всегда отображается после вызова в режиме assert отладки. Поведение каждой кнопки фиксируется в приведенной ниже таблице.

Режим ошибки stderr Выходные данные в (консоль/ _OUT_TO_STDERR ) Диалоговое окно отображения (Windows/ _OUT_TO_MSGBOX )
Abort Немедленное завершение работы с кодом выхода 3 Немедленное завершение работы с кодом выхода 3
Retry Разрыв в отладчике во время abort Разрыв в отладчике во время assert
Ignore Завершение выхода через abort Продолжить программу, как будто assert не срабатывает (может привести к неопределенному поведению, так как предварительные условия вызывающего кода не были выполнены)

Дополнительные сведения об отладке CRT см. в статьях о методах отладки CRT.

Функции _assert и _wassert являются внутренними функциями CRT. Они позволяют свести к минимуму объем кода, требуемый в объектных файлах для поддержки утверждений. Мы не рекомендуем вызывать эти функции напрямую.

Макрос assert включен как в выпусках, так и в отладочных версиях библиотек времени выполнения C, если NDEBUG они не определены. Если NDEBUG определено, макрос доступен, но не оценивает его аргумент и не влияет. Когда он включен, assert макрос вызывает _wassert его реализацию. Другие макросы утверждения, _ASSERT _ASSERTE а _ASSERT_EXPR также доступны, но они оценивают только выражения, передаваемые им, когда _DEBUG макрос определен и когда они находятся в коде, связанном с отладочной версией библиотек времени выполнения C.

Требования

Маршрут Обязательный заголовок
assert , _wassert

Подпись _assert функции недоступна в файле заголовка. Подпись _wassert функции доступна только в том случае, если NDEBUG макрос не определен.

Пример

В этой программе функция analyze_string использует макрос assert для проверки нескольких условий, связанных со строкой и длиной. Если какое-либо из условий не выполняется, программа выводит сообщение, указывающее на причину сбоя.

// crt_assert.c // compile by using: cl /W4 crt_assert.c #include #include #include void analyze_string( char *string ); // Prototype int main( void ) < char test1[] = "abc", *test2 = NULL, test3[] = ""; printf ( "Analyzing string '%s'\n", test1 ); fflush( stdout ); analyze_string( test1 ); printf ( "Analyzing string '%s'\n", test2 ); fflush( stdout ); analyze_string( test2 ); printf ( "Analyzing string '%s'\n", test3 ); fflush( stdout ); analyze_string( test3 ); >// Tests a string to see if it is NULL, // empty, or longer than 0 characters. void analyze_string( char * string ) < assert( string != NULL ); // Cannot be NULL assert( *string != '\0' ); // Cannot be empty assert( strlen( string ) >2 ); // Length must exceed 2 > 

Программа создает следующие выходные данные:

Analyzing string 'abc' Analyzing string '(null)' Assertion failed: string != NULL, file crt_assert.c, line 25 

После сбоя утверждения в зависимости от версии операционной системы и библиотеки времени выполнения может отображаться окно сообщения, содержащее примерно следующее:

A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available. 

Если отладчик установлен, нажмите кнопку Отладка , чтобы запустить его, или кнопку Закрыть программу , чтобы выйти.

Урок №109. assert и static_assert

Использование операторов условного ветвления для обнаружения ложного предположения, а также вывода сообщения об ошибке и завершения выполнения программы является настолько распространенным решением возникающих проблем, что C++ решил это дело упростить. И упростил он его с помощью assert.

Оглавление:

Стейтмент assert

Стейтмент assert (или «оператор проверочного утверждения») в языке C++ — это макрос препроцессора, который обрабатывает условное выражение во время выполнения. Если условное выражение истинно, то стейтмент assert ничего не делает. Если же оно ложное, то выводится сообщение об ошибке, и программа завершается. Это сообщение об ошибке содержит ложное условное выражение, а также имя файла с кодом и номером строки с assert. Таким образом, можно легко найти и идентифицировать проблему, что очень помогает при отладке программ.

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

#include // для assert()
int getArrayValue ( const std :: array < int , 10 >&array , int index )
// Предполагается, что значение index-а находится между 0 и 8
assert ( index >= 0 && index <= 8 ) ; // это строка 6 в Program.cpp return array [ index ] ;

Если в вышеприведенной программе вызвать getArrayValue(array, -3); , то программа выведет следующее сообщение:

Рекомендуется использовать стейтменты assert. Иногда утверждения assert бывают не очень описательными, например:

assert ( found ) ;

Если этот assert сработает, то получим:

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

Но что это нам сообщает? Очевидно, что что-то не было найдено, но что именно? Вам нужно будет самому пройтись по коду, чтобы это определить.

К счастью, есть небольшой трюк, который можно использовать для исправления этой ситуации. Просто добавьте сообщение в качестве строки C-style вместе с логическим оператором И:

assert ( found && «Animal could not be found in database» ) ;

Как это работает? Строка 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 :

#define NDEBUG
// Все стейтменты assert будут проигнорированы аж до самого конца этого файла

Некоторые IDE устанавливают NDEBUG по умолчанию, как часть параметров проекта в конфигурации Release.

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

static_assert

В C++11 добавили еще один тип assert-а — static_assert. В отличие от assert, который срабатывает во время выполнения программы, static_assert срабатывает во время компиляции, вызывая ошибку компилятора, если условие не является истинным. Если условие ложное, то выводится диагностическое сообщение.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *