问题
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 TRACINGwill tell me that tracing was defined.#if TRACINGcontrols 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
TRACINGhas a numerical value (as in#define TRACING 2 \n), cpp has a valid expression, and we haven't changed the value. - If
TRACINGhas no value (as in#define TRACING \n), the preprocessor evaluates#if (+0)tofalse
The only case this doesn't handle is
- If
TRACINGhas 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 atruevalue. The only ones that do the right thing are the boolean literalstrueandfalse.
回答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