问题
I've got a set of debug macros in tracing.hh. Whether it generates code and output is controlled by a macro flag in the real source code:
// File: foo.cc
#define TRACING 0
#include "tracing.hh"
// Away we go . . .
TRACEF("debug message");
The flag TRACING should have a value; I usually toggle between 0 and 1.
Within tracing.h,
#ifdef TRACING
will tell me that tracing was defined.#if TRACING
controls the definition of functional macros likeTRACEF()
But what if TRACING has no value? Then #if TRACING
produces an error:
In file included from foo.c:3:
tracing.hh:73:12: error: #if with no expression
How can I test if TRACING is defined but has no value?
回答1:
With Matti's suggestion and some more poking, I think the issue is this: if TRACING
has no value, we need a valid preprocessor expression in the test #if ...
. The Gnu cpp manual
says it has to evaluate to an integer expression, so we need an expression that is valid even if one of the arguments is missing. What I finally hit on is:
#if (TRACING + 0)
# . . .
- If
TRACING
has a numerical value (as in#define TRACING 2 \n)
, cpp has a valid expression, and we haven't changed the value. - If
TRACING
has no value (as in#define TRACING \n
), the preprocessor evaluates#if (+0)
tofalse
The only case this doesn't handle is
- If
TRACING
has a non-numerical value (i.e.,ON
). The cpp manual says "Identifiers that are not macros . . . are all considered to be the number zero," which evaluates tofalse
. In this case, however, it would make more sense to consider this atrue
value. The only ones that do the right thing are the boolean literalstrue
andfalse
.
回答2:
Late to the party but I found a nice trick to distinguish
#define TRACING 0
from
#define DTRACING
like this:
#if (0-TRACING-1)==1 && (TRACING+0)!=-2
#error "tracing empty"
#endif
If TRACING
is empty, the expression evaluates to 0--1
=> 1
.
If TRACING
is 0, the expression evaluates to 0-0-1
=> -1
I added an extra check in case TRACING==-2
which would make the first test pass.
This doesn't work for string literals of course.
回答3:
Would
#if defined(TRACING) && !TRACING
do the trick?
来源:https://stackoverflow.com/questions/4102351/test-for-empty-macro-definition