2010-11-04 104 views
18

我在tracing.hh中有一组调试宏。它是否生成代码和输出由真实源代码中的宏标志控制:空宏定义的测试

// File: foo.cc 
#define TRACING 0 
#include "tracing.hh" 
// Away we go . . . 
TRACEF("debug message"); 

标志TRACING应该有一个值;我通常切换0和1之间

在tracing.h,

  • #ifdef TRACING会告诉我,跟踪定义。
  • #if TRACING控制功能的宏定义一样TRACEF()

但如果追踪有没有价值呢?然后#if TRACING产生一个错误:

In file included from foo.c:3: 
tracing.hh:73:12: error: #if with no expression 

如何测试,如果跟踪被定义,但有没有价值?

回答

0

#if defined(TRACING) && !TRACING 

做的伎俩?

+0

差不多,我想。看下一个答案: – pdbj 2010-11-08 18:47:30

+4

这不幸的是不会工作。您将遇到同样的问题,因为TRACING将被删除。你最终会得到类似的结果:“#if defined(TRACING)&&!”。因此,“错误:操作员”!没有合适的操作数“将在建造时提高。 – ForceMagic 2012-06-19 00:02:43

22

随着Matti的建议和一些更多的戳,我认为问题是这样的:如果TRACING没有价值,我们需要一个有效的预处理器表达式在测试#if ...Gnu cpp manual 表示它必须评估为一个整数表达式,所以我们需要一个即使其中一个参数丢失也是有效的表达式。我终于打是:

#if (TRACING + 0) 
# . . . 
  • 如果TRACING有一个数值(如#define TRACING 2 \n),CPP具有有效的表达,我们没有改变的价值
  • 如果TRACING没有价值。 (如在#define TRACING \n),预处理器的计算结果#if (+0)false

的唯一情况下,这不处理是

  • 如果TRACING具有令牌值(,即ON)。 cpp手册中说“不是宏的标识符......都被认为是数字零,”,其值为false。然而,在这种情况下,考虑这个值是更有意义的。唯一能做正确事情的标记是布尔文字truefalse
+0

您仍然可以通过使用'#'运算符使宏成为字符串来进行运行时测试。 C++ 11可能会把它变成编译时测试(我认为使用'constexpr'可能是一种方法),但不是预处理器测试。 – 2015-11-25 11:49:37

+0

你也没有办法区分空和'TRACING'等于0 – 2018-01-31 10:24:03

+0

'#if'如果没有找到则定义为0。这是行不通的 – 2018-01-31 10:30:03

1

迟到了,但我找到了一个不错的把戏从-DTRACING区分-DTRACING=0

#if (0-TRACING-1)==1 && (TRACING+0)!=-2 
#error "tracing empty" 
#endif 

如果TRACING是空的,表达式的值为0--1 =>1

如果TRACING为0时,表达式求0-0-1 =>-1

我加入的情况下TRACING==-2额外的检查这将使第一试验合格。

这当然不适用于字符串文字。