Namespaces
Variants

assert

From cppreference.net
Definido en el encabezado <cassert>
Aserción deshabilitada
(1)
#define assert(condition) ((void)0)
(hasta C++26)
#define assert(...)       ((void)0)
(desde C++26)
Aserción habilitada
(2)
#define assert(condition) /* no especificado */
(hasta C++26)
#define assert(...)       /* no especificado */
(desde C++26)

La definición de la macro assert depende de otra macro, NDEBUG , que no está definida por la biblioteca estándar.

1) Si NDEBUG está definido como un nombre de macro en el punto del código fuente donde <cassert> o <assert.h> se incluyen, la aserción se desactiva: assert no hace nada.
2) De lo contrario, la aserción está habilitada:

assert verifica si su argumento (que debe tener tipo escalar):

  • Si el argumento compara desigual a cero, no hay efectos adicionales.
  • De lo contrario, assert crea un diagnóstico en el flujo de error estándar y llama a std::abort() .
(until C++26)

assert coloca una prueba de diagnóstico en los programas y se expande a una expresión de tipo void . __VA_ARGS__ es evaluado y convertido contextualmente a bool :

  • Si la evaluación produce true , no hay efectos adicionales.
  • De lo contrario, assert crea un diagnóstico en el flujo de error estándar y llama a std::abort() .
(since C++26)

La información de diagnóstico tiene un formato definido por la implementación, pero siempre incluye la siguiente información:

  • el texto de condition
(hasta C++26)
  • #__VA_ARGS__
(desde C++26)
  • el nombre del archivo fuente (es decir, __FILE__ )
  • el número de línea del código fuente (es decir, __LINE__ )
  • el nombre de la función contenedora (es decir, __func__ )

La expresión assert ( E ) está garantizada como una subexpresión constante , si se cumple alguna de las siguientes condiciones:

  • NDEBUG está definido en el punto donde assert es definido o redefinido por última vez, o
  • E , convertido contextualmente a bool , es una subexpresión constante que evalúa a true .
(desde C++11)

Contenidos

Parámetros

condición - expresión de tipo escalar

Notas

Debido a que assert es una macro similar a función , las comas en cualquier parte del argumento que no estén protegidas por paréntesis se interpretan como separadores de argumentos de macro. Dichas comas se encuentran frecuentemente en listas de argumentos de plantillas y en inicializaciones de lista:

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
(hasta C++26)

No existe una interfaz estandarizada para agregar un mensaje adicional a los errores de assert . Una forma portable de incluir uno es utilizar el operador coma siempre que no haya sido sobrecargado , o usar && con un literal de cadena:

assert(("There are five lights", 2 + 2 == 5));
assert(2 + 2 == 5 && "There are five lights");

La implementación de assert en Microsoft CRT no se ajusta a C++11 y revisiones posteriores, porque su función subyacente ( _wassert ) no toma ni __func__ ni un reemplazo equivalente.

Desde C++20, los valores necesarios para el mensaje de diagnóstico también pueden obtenerse de std::source_location::current() .

Aunque el cambio de assert en C23/C++26 no es formalmente un informe de defectos, el comité de C recomienda a las implementaciones que retroporten el cambio a modos anteriores.

Ejemplo

#include <iostream>
// descomentar para deshabilitar assert()
// #define NDEBUG
#include <cassert>
// Usar (void) para silenciar advertencias de no uso.
#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"); // la aserción falla
    std::cout << "Execution continues past the last assert\n"; // Sin salida
}

Salida posible:

Checkpoint #1
Checkpoint #2
Checkpoint #3
Checkpoint #4
main.cpp:23: int main(): Assertion `((void)"Failed", 2 + 2 == 5)' failed.
Aborted

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 2234 C++11 assert no podía usarse en expresiones constantes puede usarse

Véase también

contract_assert declaración (C++26) verifica una condición interna durante la ejecución
static_assert declaración (C++11) realiza verificación de aserciones en tiempo de compilación
provoca la terminación anormal del programa (sin limpieza)
(función)
Documentación C para assert