测试空宏定义

问题描述 投票:0回答:3

我在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 是否已定义但没有值?

preprocessor c-preprocessor
3个回答
32
投票

根据 Matti 的建议和更多的探索,我认为问题是这样的:如果

TRACING
没有值,我们需要在测试中使用有效的预处理器表达式
#if ...
Gnu cpp 手册 说它必须计算为整数表达式,因此我们需要一个即使缺少其中一个参数也有效的表达式。我最终想到的是:

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

唯一不能处理的情况是

  • 如果
    TRACING
    具有非数值(
    ON
    )。 cpp 手册说“不是宏的标识符...都被认为是数字零,”,其计算结果为
    false
    。然而,在这种情况下,将其视为
    true
    值更有意义。唯一做正确事情的是布尔文字
    true
    false

10
投票

聚会迟到了,但我找到了一个很好的区分技巧

#define TRACING 0

来自

#define TRACING

像这样:

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

如果

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

如果

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

我添加了一个额外的检查,以防万一

TRACING==-2
这将使第一个测试通过。

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


0
投票

#if defined(TRACING) && !TRACING

有技巧吗?

© www.soinside.com 2019 - 2024. All rights reserved.