Test for empty macro definition

帅比萌擦擦* 提交于 2019-12-29 05:47:06

问题


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 like TRACEF()

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) to false

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 to false. In this case, however, it would make more sense to consider this a true value. The only ones that do the right thing are the boolean literals true and false.



回答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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!