Пространства имён
Варианты
Действия

assert

Материал из cppreference.com
< cpp‎ | error
 
 
Библиотека диагностики
Обработка исключений
Сбои обработки исключений
(до C++17*)
(до C++17*)
(C++11)(до C++17*)    
(до C++17*)
Коды ошибок
Коды ошибок
Категории исключений
(ТС TM)
Поддержка системных ошибок
(C++11)
(C++11)
Утверждения
assert
Трассировка стека
 
Определено в заголовочном файле <cassert>
#ifdef NDEBUG

#  define assert(условие) ((void)0)
#else
#  define assert(условие) /*определено реализацией*/

#endif

Определение макроса assert зависит от другого макроса, NDEBUG, который не определён в стандартной библиотеке.

Если NDEBUG определён как имя макроса в той точке исходного кода, где включены <cassert> или <assert.h>, тогда assert ничего не делает.

Если NDEBUG не определён, то assert проверяет, равен ли его аргумент (который должен иметь скалярный тип) нулю. Если это так, assert выводит специфичную для реализации диагностическую информацию в стандартный вывод ошибок и вызывает std::abort. Диагностическая информация должна включать текст выражения, а также значения предопределённой переменной __func__ и (начиная с C++11) предопределённые макросы __FILE__ и __LINE__.

Выражение assert(E) гарантированно будет константным подвыражением, если либо

  • NDEBUG определяется в точке, где assert последний раз определялся или переопределялся (т.е. где заголовок <cassert> или <assert.h> был включен последний раз); либо
  • E, контекстно преобразованное в bool, представляющее собой подвыражение-константу, результатом которой является true.
(начиная с C++17)

Содержание

[править] Параметры

условие выражение скалярного типа

[править] Возвращаемое значение

(нет)

[править] Примечание

Поскольку assert является макросом, подобным функции, запятые в любом месте условия, не защищённые круглыми скобками, интерпретируются как разделители аргументов макроса. Такие запятые часто встречаются в списках аргументов шаблонов и при инициализации списком:

assert(std::is_same_v<int, int>); // ошибка: assert не принимает два аргумента
assert((std::is_same_v<int, int>)); // OK: один аргумент
static_assert(std::is_same_v<int, int>); // OK: не макрос
std::complex<double> c;
assert(c == std::complex<double>{0, 0}); // ошибка
assert((c == std::complex<double>{0, 0})); // OK

Не существует стандартизированного интерфейса для добавления дополнительного сообщения к ошибкам assert. Переносимый способ включить его это использовать оператор запятая, если он не был перегружен, или использовать && со строковым литералом:

assert(("Есть пять огней", 2 + 2 == 5));
assert( (2 + 2 == 5) && "Есть пять огней");

Реализация assert в Microsoft CRT не соответствует C++11 и более поздним версиям, поскольку её базовая функция (_wassert) не принимает ни __func__, ни эквивалентную замену.

[править] Пример

#include <iostream>
// раскомментируйте, чтобы отключить assert()
// #define NDEBUG
#include <cassert>
 
// Используйте (void), чтобы отключить неиспользуемые предупреждения.
#define assertm(exp, msg) assert(((void)msg, exp))
 
int main()
{
    assert(2+2==4);
    std::cout << "Контрольная точка #1\n";
 
    assert((void("void помогает избежать предупреждения о"
                 "'неиспользованном значении'"), 2*2==4));
    std::cout << "Контрольная точка #2\n";
 
    assert((010+010==16) && "Ещё один способ добавить сообщение об утверждении");
    std::cout << "Контрольная точка #3\n";
 
    assertm((2+2)%3==1, "Ожидайте ожидаемого");
    std::cout << "Контрол��ная точка #4\n";
 
    assertm(2+2==5, "Есть пять огней"); // утверждение терпит неудачу
    std::cout << "Выполнение продолжается после последнего утверждения\n"; // Нет
}

Возможный вывод:

Контрольная точка #1
Контрольная точка #2
Контрольная точка #3
Контрольная точка #4
main.cpp:23: int main(): Assertion '((void)"Есть пять огней", 2+2==5)' failed.
Aborted

[править] Смотрите также

объявление static_assert(C++11) выполняет проверку утверждения во время компиляции[править]
вызывает аварийное завершение программы (без очистки)
(функция) [править]