测试空宏定义

时间:2010-11-04 23:30:58

标签: preprocessor c-preprocessor

我在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()

但是如果TRACING没有价值怎么办?然后#if TRACING产生错误:

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

如何测试是否已定义TRACING但没有值?

3 个答案:

答案 0 :(得分:23)

根据Matti的建议和更多的讨论,我认为问题是:如果TRACING没有值,我们需要在测试#if ...中有一个有效的预处理器表达式。 Gnu cpp manual {{3}} 说它必须求值为整数表达式,所以我们需要一个有效的表达式,即使其中一个参数缺失也是如此。我最终得到的是:

#if (TRACING + 0)
#  . . .
  • 如果TRACING有一个数值(如#define TRACING 2 \n)中所示,则cpp有一个有效的表达式,我们没有更改该值。
  • 如果TRACING没有值(如#define TRACING \n中所述),则预处理器会将#if (+0)评估为false

唯一无法解决的案例是

  • 如果TRACING有令牌值(ON)。 cpp手册说“非宏的标识符......都被认为是数字零,”,其评估为false。但是,在这种情况下,将此true值视为更有意义。做正确事情的唯一标记是布尔文字truefalse

答案 1 :(得分:2)

参加晚会但我发现了一个很好的方法来区分-DTRACING=0-DTRACING

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

如果TRACING为空,则表达式的计算结果为0--1 => 1

如果TRACING为0,则表达式的计算结果为0-0-1 => -1

我在TRACING==-2的情况下添加了额外的检查,这将使第一次测试通过。

当然,这对字符串文字不起作用。

答案 2 :(得分:0)

#if defined(TRACING) && !TRACING

诀窍?