¿Qué definición de preprocesador se debe usar para especificar secciones de código de depuración?
Use #ifdef _DEBUG
o #ifndef NDEBUG
o ¿hay una mejor manera de hacerlo, por ejemplo #define MY_DEBUG
?
Creo que _DEBUG
es específico de Visual Studio, ¿es NDEBUG estándar?
Sí, es una macro estándar con la semántica "No depurar" para los estándares C89, C99, C ++ 98, C ++ 2003, C ++ 2011, C ++ 2014. No hay
_DEBUG
macros en los estándares.El estándar C ++ 2003 envía al lector en la "página 326" en "17.4.2.1 Encabezados" al estándar C.
En C89 (los programadores de C llamaron a este estándar como estándar C) en la sección "4.2 DIAGNÓSTICO" se dijo
Si observa el significado de las
_DEBUG
macros en Visual Studio https://msdn.microsoft.com/en-us/library/b0084kay.aspx , se verá que esta macro se define automáticamente por su elección de versión de biblioteca de tiempo de ejecución de idioma.fuente
Confío en
NDEBUG
que es el único cuyo comportamiento está estandarizado en compiladores e implementaciones (consulte la documentación para la macro de aserción estándar). La lógica negativa es un pequeño salto de velocidad de legibilidad, pero es un idioma común al que puede adaptarse rápidamente.Confiar en algo así
_DEBUG
sería confiar en un detalle de implementación de un compilador particular y la implementación de la biblioteca. Otros compiladores pueden o no elegir la misma convención.La tercera opción es definir su propia macro para su proyecto, lo cual es bastante razonable. Tener su propia macro le brinda portabilidad entre las implementaciones y le permite habilitar o deshabilitar su código de depuración independientemente de las afirmaciones. Aunque, en general, desaconsejo tener diferentes clases de información de depuración que estén habilitadas en el momento de la compilación, ya que causa un aumento en el número de configuraciones que tiene que construir (y probar) para obtener un beneficio posiblemente pequeño.
Con cualquiera de estas opciones, si usa código de terceros como parte de su proyecto, tendrá que saber qué convención usa.
fuente
#if !defined(NDEBUG)
<- @HostileFork ¿no es eso lo que querías decir?#if
no#ifdef
?#ifdef NDEBUG
... pero luego preste especial atención a la lógica negativa con#if !defined(NDEBUG)
. De lo contrario, es un poco difícil atrapar la n#ifndef NDEBUG
"La macro
NDEBUG
controla si lasassert()
declaraciones están activas o no.En mi opinión, eso está separado de cualquier otra depuración, por lo que uso algo más que
NDEBUG
para controlar la información de depuración en el programa. Lo que uso varía, dependiendo del marco con el que estoy trabajando; diferentes sistemas tienen diferentes macros habilitadoras, y yo uso lo que sea apropiado.Si no hay un marco, usaría un nombre sin un guión bajo; esos tienden a estar reservados para 'la implementación' y trato de evitar problemas con las colisiones de nombres, doblemente cuando el nombre es una macro.
fuente
#if
código controlado en la otra.assert(huge_object.IsValid());
podría ser lento mientras queassert(ptr != nullptr);
probablemente no lo sea. Estoy de acuerdo con Jonathan en que el registro y el seguimiento probablemente deberían ser distintos de las afirmaciones, al menos en proyectos más grandes, pero no pienso en el registro o el seguimiento como código de depuración, por lo que solicité una aclaración.Sea consistente y no importa cuál. Además, si por algún motivo debe interoperar con otro programa o herramienta utilizando un determinado identificador de DEPURACIÓN, es fácil hacerlo
fuente
Lamentablemente
DEBUG
está sobrecargado. Por ejemplo, se recomienda generar y guardar siempre un archivo pdb para las versiones RELEASE. Lo que significa una de las-Zx
banderas y la-DEBUG
opción de enlazador. Mientras se_DEBUG
relaciona con versiones especiales de depuración de la biblioteca en tiempo de ejecución, como llamadas amalloc
yfree
. LuegoNDEBUG
deshabilitará las aserciones.fuente