Solución:
Mira esta línea:
extern void __assert (const char *msg, const char *file, int line);
__assert
es una función que toma un mensaje de aserción, un nombre de archivo y un número de línea como argumentos. Básicamente, este es el método que imprime el mensaje de error y finaliza el programa cuando falla la afirmación.
Luego, mire la definición de macro anterior:
#define assert(EX) (void)((EX) || (__assert (#EX, __FILE__, __LINE__),0))
Define el assert(EX)
macro entonces, primero verifica la expresión EX y (debido a la operación de cortocircuito del C ++ ||
operador) solo si falla, llama al __assert
función y pasa la excepción de aserción fallida como una cadena, y la ubicación exacta de la assert()
llamada al método en sus archivos de origen. Con este truco del preprocesador, la biblioteca de aserciones logra que cuando escribe lo siguiente en su programa
assert(a == 0);
y su afirmación falla durante la ejecución del programa, obtiene la información detallada
Assertion failed: a == 0 at program.c, line 23
mensaje de error que le ayuda a identificar la ubicación exacta donde fallaba la afirmación en su código.
los (void)
parte es solo para asegurarse de que el compilador no publique algunas advertencias sobre el resultado no utilizado de la (EX) || 0
expresión, vea las otras respuestas, los chicos lo explicaron bien.
El preprocesador restante define NDEBUG
se utiliza para activar la generación de aserciones en todo momento de la compilación, su ejecutable resultante será más pequeño y más rápido.
__assert
es parte de la implementación; en este caso, una función en la biblioteca que se llamará en caso de falla de aserción. Y el (void)
es simplemente cerrar las advertencias del compilador sobre los resultados no utilizados de la ||
operador.