Can you #define a comment in C?

2019-03-11 17:57发布

I'm trying to do a debug system but it seems not to work.

What I wanted to accomplish is something like this:

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

Is there a way to do that? I have lots of debug messages and I won't like to do:

if (DEBUG)
    printf(...)

code

if (DEBUG)
    printf(...)

...

12条回答
爷、活的狠高调
2楼-- · 2019-03-11 18:33

A common trick is to do this:

#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;
}

This way you have the whole power of printf() available to you, but you have to put up with the double brackets to make the macro work.

The point of the double brackets is this: you need one set to indicate that it's a macro call, but you can't have an indeterminate number of arguments in a macro in C89. However, by putting the arguments in their own set of brackets they get interpreted as a single argument. When the macro is expanded when DEBUG is defined, the replacement text is the word printf followed by the singl argument, which is actually several items in brackets. The brackets then get interpreted as the brackets needed in the printf function call, so it all works out.

查看更多
姐就是有狂的资本
3楼-- · 2019-03-11 18:34

In C++17 I like to use constexpr for something like this

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

Then you can do

if constexpr (DEBUG) /* debug code */

The caveats are that, unlike a preprocessor macro, you are limited in scope. You can neither declare variables in one debug conditional that are accessible from another, nor can they be used at outside function scopes.

查看更多
Explosion°爆炸
4楼-- · 2019-03-11 18:39

It's been done. I don't recommend it. No time to test but the mechanism is kind of like this:

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

This works if your compiler processes // comments in the compiler itself (there's no guarantee like the ANSI guarantee that there are two passes for /* comments).

查看更多
Explosion°爆炸
5楼-- · 2019-03-11 18:43

I use this construct a lot:

#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

This way I can tell in my console which program is giving which error message... also, I can search easily for my error messages...

Personally, I don't like #defining just part of an expression...

查看更多
叼着烟拽天下
6楼-- · 2019-03-11 18:48

You can take advantage of if. For example,

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

Compiler will remove these unreachable code if you set a optimization flag like -O2. This method also useful for std::cout.

查看更多
来,给爷笑一个
7楼-- · 2019-03-11 18:51

С99 way:

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

Well, this one doesn't require C99 but assumes compiler has optimization turned on for release version:

#ifdef DEBUG
    #define printd printf
#else
    #define printd if (1) {} else printf
#endif
查看更多
登录 后发表回答