Estoy tratando de hacer un sistema de depuración, pero no parece funcionar.

Lo que yo quería hacer es algo como esto:

#ifndef DEBUG
    #define printd //
#else
    #define printd printf
#endif

Hay una manera de hacer eso? Tengo un montón de mensajes de depuración y no me gusta hacer:

if (DEBUG)
    printf(...)

code

if (DEBUG)
    printf(...)

...
  • Directo duplicado de stackoverflow.com/questions/1644868/… y probablemente otros también.
  • el caso de uso (la creación de una depuración de impresión sólo macro) es un duplicado de la stackoverflow.com/questions/1644868/…, pero el literal de la pregunta (¿puedo incluir // en un #define) no es – y el literal de la pregunta es muy interesante y útil a los demás. La superposición es lamentable, pero hay distintos pregunta aquí, que tiene un valor; no debería ser cerrado.
  • El título es una ‘XY Problema’ — la solución a lo que el usuario está tratando de lograr es en la nominada duplicado, pero la pregunta está pidiendo algo tangencial que incluso no lograr lo que quieren.
  • si usted piensa que el título es un problema o no, yo simplemente no han encontrado las respuestas o el pensamiento de hacer las cosas de cierta manera si yo no he hecho clic en este título en los resultados de búsqueda de Google. Para mí, la pregunta era más acerca de cómo el código de la tira de la producción sin necesidad de #ifdefs en todas partes, y gracias a OP tangencial pregunta he encontrado ideas que me puso en el camino correcto. Yo no hubiera buscado una pregunta sobre la «impresión de depuración»–que simplemente no es mi caso de uso!
InformationsquelleAutor Ben B. | 2009-11-23

12 Comentarios

  1. 29

    No, No puede. Los comentarios se quitan el código antes de cualquier procesamiento de directivas de preprocesamiento de comenzar. Por esta razón, usted no puede incluir el comentario en una macro.

    También, cualquier intento de «forma» en un comentario posterior mediante el uso de cualquier macro engaño no están garantizados para trabajar. El compilador no está obligado a reconocer «la tarde» comentarios como los comentarios.

    La mejor manera de poner en práctica lo que quieres es usar macros con argumentos variables en C99 (o, tal vez, utilizando el compilador de extensiones).

  2. 20

    Un truco común es hacer esto:

    #ifdef DEBUG
      #define OUTPUT(x) printf x
    #else
      #define OUTPUT(x)
    #endif
    
    #include <stdio.h>
    int main(void)
    {   
      OUTPUT(("%s line %i\n", __FILE__, __LINE__));
    
      return 0;
    }

    De esta manera usted tiene todo el poder de printf() disponibles para usted, pero usted tiene que poner para arriba con el doble paréntesis para hacer la macro de trabajo.

    El punto del dobles corchetes es esta: usted necesita uno para indicar que es una llamada de macro, pero usted no puede tener un número indeterminado de argumentos en una macro en C89. Sin embargo, mediante la presentación de los argumentos en su propio conjunto de corchetes son interpretados como único argumento. Cuando la macro se expande cuando DEBUG se define, el texto de reemplazo es la palabra printf seguido por el dual argumento, que es en realidad varios elementos entre corchetes. Los corchetes, a continuación, interpretados como los soportes necesarios en el printf llamada a la función, por lo que todo funciona.

    • ¿por qué no utilizar printf(x) en el 1er macro ? no iba a funcionar ?
    • también, usted puede usar la SALIDA(x…) printf(x) para evitar la doble ().
    • Esto no funciona si quería un número variable de argumentos. Ver texto explicativo para más detalles.
  3. 18

    С99 manera:

    #ifdef DEBUG
        #define printd(...) printf(__VA_ARGS__)
    #else
        #define printd(...)
    #endif

    Bien, este no requiere de C99, pero se supone compilador ha de optimización de encendido para la versión de lanzamiento:

    #ifdef DEBUG
        #define printd printf
    #else
        #define printd if (1) {} else printf
    #endif
    • Correcto, pero no es muy portátil.
    • Añadido manera portable 🙂
    • Mucho mejor, pero de nuevo la versión portátil no deshabilitar las comprobaciones de validez de los argumentos. La manera correcta de hacerlo en la no-C99 aplicación se da en Tim respuesta.
    • Y ese es su lado bueno creo que. Por qué deshabilitar la comprobación de validez en el código que va a ser real en las versiones de depuración?
    • Simple: debido a que el código podría ser válido en la liberación de versiones. No hay nada malo con la depuración de código no es válido en la liberación. Por otra parte, que es la manera que es la mayoría del tiempo.
    • Aunque esta pregunta es muy viejo y ya ha sido contestada estoy intrigado con tu comentario. Podría usted proporcione o punto con un ejemplo en el código de depuración podría ser válido en la liberación de versiones? Muchas gracias.

  4. 8

    Usted puede poner toda su depuración llamar a una función, vamos a llamarlo printf_debug y poner el DEBUG dentro de esta función.
    El compilador se encargará de optimizar la función vacía.

    • Gracias, la cordura en el pasado .. excepto en su mayoría el trabajo del preprocesador.
    • En este caso, usted podría simplemente llame a su función printd
    • Que no, no se desactiva la evaluación de los argumentos y no deshabilitar el requisito de que los argumentos sean válidos (como, declaró, por ejemplo). En otras palabras, no hacer lo que se le pidió.
    • si de cualquier tipo de enlace optimización del tiempo es de hecho, el compilador en línea vacía funciones y quitar código muerto para la evaluación de argumentos.
    • El problema es que simplemente no va a compilar, si los argumentos no son válidos en la liberación de contexto. No voy a entrar a la «optimización».
  5. 5

    En algunos compiladores (incluyendo MS VS2010) esto va a funcionar,

    #define CMT / ## /

    pero no beneficiarios para todos los compiladores.

  6. 2

    La forma estándar es el uso de

    #ifndef DEBUG
        #define printd(fmt, ...)  do { } while(0)
    #else
        #define printd(fmt, ...) printf(fmt, __VA_ARGS__)
    #endif

    De esa manera, al agregar un punto y coma al final, no lo que desea.
    Como no hay ninguna operación que el compilador compila el «do…while»

  7. 1

    No probados:
    Edit: Probado, usando por mí mismo, por ahora 🙂

    #define DEBUG 1
    #define printd(fmt,...) if(DEBUG)printf(fmt, __VA_ARGS__)

    requiere no sólo definir DEBUG pero también le dan un no-zer0 valor.

    Apéndice:
    También funciona bien con std::cout

  8. 1

    En C++17 me gusta usar constexpr para algo como esto

    #ifndef NDEBUG
    constexpr bool DEBUG = true;
    #else
    constexpr bool DEBUG = false;
    #endif

    Entonces usted puede hacer

    if constexpr (DEBUG) /* debug code */

    La cuenta que, a diferencia de una macro de preprocesador, que son de alcance limitado. Usted no puede declarar variables en uno de depuración condicional que son accesibles de otro, ni puede ser utilizada en el exterior de la función de los ámbitos.

    • Esta no es una respuesta, la pregunta es etiquetados C, y la respuesta es para C++. Esos son dos idiomas diferentes.
  9. 0

    Como señaló McKay, que se ejecutará en problemas si usted simplemente intentar sustituir printd con //. En su lugar, puedes utilizar variadric macros para reemplazar printd con una función que no hace nada, como en el siguiente.

    #ifndef DEBUG
        #define printd(...) do_nothing()
    #else
        #define printd(...) printf(__VA_ARGS__)
    #endif
    
    void do_nothing() { ; }

    El uso de un depurador como GDB puede ayudar también, pero a veces una rápida printf es suficiente.

  10. 0

    Yo uso este constructo mucho:

    #define DEBUG 1
    #if DEBUG
    #if PROG1
    #define DEBUGSTR(msg...)        { printf("P1: "); printf( msg); }
    #else
    #define DEBUGSTR(msg...)        { printf("P2: "); printf( msg); }
    #endif
    #else
    #define DEBUGSTR(msg...)    ((void) 0)
    #endif

    De esta manera me doy cuenta en mi consola el programa que está dando que mensaje de error… además, me pueden buscar fácilmente para mi los mensajes de error…

    Personalmente, no me gusta #definir sólo una parte de una expresión…

  11. 0

    Que se ha hecho. No lo recomiendo. No hay tiempo para probar, pero el mecanismo es como este:

     #define printd_CAT(x) x ## x
     #ifndef DEBUG
        #define printd printd_CAT(/)
     #else
        #define printd printf
     #endif

    Esto funciona si el compilador procesos //comentarios en el propio compilador (no hay ninguna garantía como la ANSI garantía de que hay dos pases /* los comentarios).

  12. 0

    Usted puede tomar ventaja de if. Por ejemplo,

    #ifdef debug
        #define printd printf
    #else 
        #define printd if (false) printf
    #endif

    Compilador va a quitar estos código inalcanzable si se establece un ajuste de optimización como -O2. Este método también es útil para std::cout.

Dejar respuesta

Please enter your comment!
Please enter your name here