assert
Определён в заголовочном файле <cassert> | ||
|---|---|---|
| Отключённое утверждение | ||
#define assert(condition) ((void)0) | (1) | (до C++26) |
#define assert(...) ((void)0) | (начиная с C++26) | |
| Включённое утверждение | ||
#define assert(condition) /* unspecified */ | (2) | (до C++26) |
#define assert(...) /* unspecified */ | (начиная с C++26) |
Определение макроса assert зависит от другого макроса, NDEBUG, который не определён стандартной библиотекой.
NDEBUG определён как имя макроса в точке исходного кода, где подключается <cassert> или <assert.h>, утверждение отключается: assert ничего не делает.|
| (до C++26) |
|
| (начиная с C++26) |
Формат диагностической информации определяется реализацией, но она всегда включает следующие сведения:
| (до C++26) |
| (начиная с C++26) |
- имя исходного файла (то есть
__FILE__) - номер строки исходного файла (то есть
__LINE__) - имя охватывающей функции (то есть
__func__)
| Гарантируется, что выражение
| (начиная с C++11) |
Параметры
| condition | - | выражение скалярного типа |
Примечания
| Поскольку assert(std::is_same_v<int, int>); // error: assert does not take two arguments
assert((std::is_same_v<int, int>)); // OK: one argument
static_assert(std::is_same_v<int, int>); // OK: not a macro
std::complex<double> c;
assert(c == std::complex<double>{0, 0}); // error
assert((c == std::complex<double>{0, 0})); // OK
| (до C++26) |
Стандартизованного интерфейса для добавления дополнительного сообщения к ошибкам assert нет. Переносимый способ добавить такое сообщение — использовать оператор «запятая», если он не был перегружен, или использовать && со строковым литералом:
assert(("There are five lights", 2 + 2 == 5));
assert(2 + 2 == 5 && "There are five lights");
Реализация assert в Microsoft CRT не соответствует C++11 и более поздним редакциям, поскольку используемая ею функция (_wassert) не принимает ни __func__, ни эквивалентную замену.
Начиная с C++20 значения, необходимые для диагностического сообщения, также можно получить из std::source_location::current().
Хотя изменение assert в C23/C++26 формально не является отчётом об ошибке, комитет C рекомендует реализациям переносить это изменение и в старые режимы.
Пример
#include <iostream>
// uncomment to disable assert()
// #define NDEBUG
#include <cassert>
// Use (void) to silence unused warnings.
#define assertm(exp, msg) assert((void(msg), exp))
int main()
{
assert(2 + 2 == 4);
std::cout << "Checkpoint #1\n";
assert((void("void helps to avoid 'unused value' warning"), 2 * 2 == 4));
std::cout << "Checkpoint #2\n";
assert((010 + 010 == 16) && "Yet another way to add an assert message");
std::cout << "Checkpoint #3\n";
assertm((2 + 2) % 3 == 1, "Success");
std::cout << "Checkpoint #4\n";
assertm(2 + 2 == 5, "Failed"); // assertion fails
std::cout << "Execution continues past the last assert\n"; // No output
}
Возможный вывод:
Checkpoint #1 Checkpoint #2 Checkpoint #3 Checkpoint #4 main.cpp:23: int main(): Assertion `((void)"Failed", 2 + 2 == 5)' failed. Aborted
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были ретроспективно применены к ранее опубликованным стандартам C++.
| DR | Применён к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
| LWG 2234 | C++11 |
assert нельзя было использовать в константном выражении | можно использовать |
См. также
инструкция contract_assert (C++26) | проверяет внутреннее условие во время выполнения |
объявление static_assert (C++11) | выполняет проверку утверждений во время компиляции |
| вызывает аварийное завершение программы (без очистки) (функция) |
|
Документация по C для assert |
|
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/error/assert