2009-03-06 10 views
12

Necesito ejecutar build de nave solo y debo afirmar en ciertas condiciones en la versión de lanzamiento para ver si el problema está solucionado. ¿Cómo lo hago?Cómo poner assert en compilaciones de lanzamiento en C/C++

+0

¿Qué plataforma? Windows y Visual Studio? –

+0

En general, no se recomienda mantener las aserciones en las compilaciones de Release. Sin embargo, puede que tenga una buena razón para hacerlo; aún así, tampoco se puede llamar "assertion" y en este caso no debería usar las mismas llamadas a funciones. – moala

Respuesta

14

UNDEFINE la macro NDEBUG - usted puede hacer esto a nivel local en todo el afirma que desea permanecer en la construcción:

#undef NDEBUG 
#include <assert.h> // reinclude the header to update the definition of assert() 

o hacer lo que hay que hacer para que su proceso de construcción no define la macro NDEBUG en El primer lugar.

+0

si la assert.h incluida en el archivo pch, podría no funcionar. –

+0

Lo he intentado, no siempre funciona. Si pongo esto como las dos primeras líneas en mi .cpp, no hace nada, pero funciona cuando lo coloco justo encima de mi main(). –

+0

Entonces parece que algo debe estar redefiniendo NDEBUG e incluyendo 'assert.h' de nuevo (posiblemente algún otro encabezado que se esté incluyendo). –

2

El comportamiento predeterminado de ASSERT es abortar el programa bajo la configuración de depuración, pero esto generalmente se convierte en una operación no operativa en una configuración de versión. Creo que lo hace comprobando la existencia de la macro preprocesador NDEBUG. No estoy trabajando en este momento, así que no puedo verificar esto.

Creo que la manera más fácil de evitar esto es modificar la configuración de depuración para convertir todas las optimizaciones al mismo nivel que Release (O2 de la memoria), y luego reconstruir el software. Esto le dará el rendimiento y la velocidad equivalentes de una compilación de Release, pero aún así definirá la macro de preprocesador de NDEBUG, lo que significa que todos los ASSERT fallidos seguirán causando la interrupción del programa. Solo recuerde volver a cambiar el nivel de optimización más adelante, de lo contrario tendrá problemas para depurarse en la configuración de depuración.

En general, ASSERTs solo debe usarse para programar precondiciones y nunca para manejar fallas en el software de envío. Desea fallar rápidamente durante el desarrollo, pero con gracia delante de un usuario.

16

¿Por qué no definir su propia aserción:

#define assert(x) MessageBox(...); 
+4

Votado porque es la única sugerencia de sain aquí. Aunque recomiendo poner un número de línea y también la explicación de lo que salió mal. Aunque lo siguiente es también diseñar su propio sistema de bloqueo para que cuando afirme que se active, haga un volcado de memoria que se le envíe automáticamente. – Chad

+2

Me gusta esto, pero me gustaría hacer una sugerencia tardía de seis años: use un nombre diferente para su afirmación de que le gustaría existir en las compilaciones de versión y depuración como 'ndbgassert' o similar. De esa forma puedes elegir entre los dos. –

+0

¿Cómo se afirma un MessageBox? ¿No debería verificar la condición primero? – yairchu

3

Sólo tiene que llamar directamente a la parte de la definición de la macro assert que está activo en modo de lanzamiento.

Puede encontrar definiciones muy útiles para aserciones en C++ en this great article by Miro Samek. Luego puede modificarlos un poco para satisfacer sus necesidades. Por ejemplo, puede crear otra macro, release_assert, que haga lo mismo que afirmar, independientemente de si está en modo de liberación o depuración.

1

Me gusta definirlo para arrojar algún tipo de assert_exception derivado de un std :: runtime_error. Luego tómalo en algún lado y haz algo útil.

1

En realidad, yo enviaría la versión de depuración si puede vivir con ella. Si no necesita el rendimiento de la versión de lanzamiento, use la depuración. Tiende a tener menos errores (esto es una simplificación excesiva y si el programa está libre de errores, simplemente cambiar a versión no cambia esto, pero debido a cosas que el compilador hace en modo de depuración, los errores pueden no ocurrir y/o tener consecuencias menos severas).

Quizás también sea posible optimizar solo las partes críticas del tiempo de su programa.

También puede simplificar la depuración.

+4

Bueno, en Visual C++, no puede entregar legalmente los tiempos de ejecución de depuración de C++, por lo que entregar binarios de depuración al cliente puede ser un problema si compila con los tiempos de ejecución de DLL (es decir,/MD o/MDd). – paercebal

+1

Aunque esta respuesta es downvoted, creo que llega a un punto importante, que es la noción de que cambiar una serie de variables entre lo que el desarrollador prueba principalmente [la versión de depuración] y lo que se libera no es necesariamente una buena idea . Los desarrolladores experimentados darán fe del hecho de que las versiones Release y Debug a menudo exhiben un comportamiento diferente. – Cameron

0

Al usar Visual Studio, puede definir la definición del precompilador NDEBUG como afirmaciones activas en la compilación Release.

Por ejemplo, puede establecer $ (undefesTheNDEBUG) en la configuración de Projekt para la opción/T y luego definir el entorno undefesTheNDEBUG variable para NDEBUG (SET undefesTheNDEBUG = NDEBUG) o pasarlo junto con msbuild (/ t: undefesTheNDEBUG = NDEBUG)