assert.h является заголовочный файл в стандартной библиотеке на языке программирования C , который определяет C препроцессора макрос assert()
. [1] [2] В C ++ он также доступен через
файл заголовка.
Утверждать
assert (а! = 1);
Это макрос, реализующий утверждение времени выполнения , которое можно использовать для проверки предположений, сделанных программой, и печати диагностического сообщения, если это предположение ложно.
При выполнении, если выражение ложно (то есть сравнивается с 0), assert()
запишет информацию о вызове, который не удался, stderr
а затем вызовет abort()
. Информация, в которую он пишет, stderr
включает:
- имя исходного файла (предопределенный макрос
__FILE__
) - номер исходной строки (предопределенный макрос
__LINE__
) - исходная функция (предопределенный идентификатор
__func__
) (добавлен в C99 ) - текст выражения, которое оценивается как 0 [1]
Пример вывода программы, скомпилированной в Linux:
program: program.c: 5: main: Утверждение `a! = 1 'не выполнено.Прервать (ядро выгружено)
Программисты могут исключить утверждения, просто перекомпилировав программу, без изменения исходного кода: если макрос NDEBUG
определен до включения
, assert()
макрос может быть определен просто как:
#define assert (игнорировать) ((void) 0)
и поэтому не влияет на модуль компиляции, даже не оценивая его аргумент. Поэтому переданные выражения неassert()
должны содержать побочных эффектов, поскольку они не будут происходить, если отладка отключена. Например:
assert (x = получает ());
не будет читать строку и не назначать x, когда отладка отключена.
Дополнительное сообщение
Не существует стандартизированного варианта assert()
, включающего сообщение об ошибке. Тем не менее, этого можно добиться с помощью оператора запятой , который отбрасывает все предыдущие значения и сохраняет только последнее:
assert (( "оруэлловский" , 2 + 2 == 5 ));
Получится что-то похожее на:
program: program.c: 5: main: Утверждение `(" Оруэлловское ", 2 + 2 == 5) 'не выполнено.Прервать
Более удобный синтаксис можно создать с помощью макроса, здесь используется имя, которое Microsoft использует [3] для аналогичного макроса:
#define _ASSERT_EXPR (тест, сообщение) assert (((void) (сообщение), тест)) _ASSERT_EXPR ( 2 + 2 == 5 , «оруэлловский» );
Статическое утверждение
static_assert ( sizeof ( int ) > 20 , «Мне нужны огромные целые числа» );
В C ++ 11 добавлено аналогичное ключевое слово static_assert
[4], которое контекстно преобразует постоянное выражение в bool
и печатает сообщение (необязательно, начиная с C ++ 17 [4] ) во время компиляции, если оно ложно. Это можно смоделировать с помощью макроса и шаблонов, хотя, вероятно, в этом нет необходимости, поскольку большинство современных компиляторов C ++ поддерживают эту функцию C ++ 11.
Эта функция была официально добавлена в C11 как ключевое слово _Static_assert
с идентичным использованием, а
также static_assert
добавлен макрос для удобства .
Можно смоделировать статическое утверждение в более старых версиях C с помощью макроса:, #define static_assert(cond, str) char _temp[-!((void)str, (cond))]
хотя результирующая ошибка является загадочной. (Это вызывает ошибку, потому что C допускает массивы нулевой длины, но не массивы отрицательной длины.) Версия статического утверждения Gnulib использует sizeof и структуру, чтобы вызвать аналогичную ошибку. [5]
Пример
#include #include int main () { int я ; для ( я = 0 ; я <= 9 ; я ++ ) { утверждение ( я <= 4 ); printf ( "я =% d \ n " , я ); } возврат 0 ; }
я = 0я = 1я = 2я = 3я = 4assert: example.c: 10: main: Утверждение `i <= 4 'не выполнено.Прервано
Внешние ссылки
- Единая спецификация UNIX , выпуск 7 от The Open Group : проверка утверждения программы - Справочник по базовым определениям,
Рекомендации
- ^ a b Международный стандарт языка программирования C (C99), ISO / IEC 9899: 1999, стр. 169
- ^ [Справочник программиста C / C ++ страницы] . Архивировано из оригинала на 2012-06-30 . Проверено 23 марта 2012 .
- ^ «Макросы _ASSERT, _ASSERTE, _ASSERT_EXPR» .
- ^ a b https://en.cppreference.com/w/cpp/language/static_assert
- ^ "gnulib / lib / verify.h" . coreutils. 24 ноября 2019.