Preprocessor 测试宏定义是否为空
我在tracing.hh中有一组调试宏。它是否生成代码和输出由实际源代码中的宏标志控制:Preprocessor 测试宏定义是否为空,preprocessor,c-preprocessor,Preprocessor,C Preprocessor,我在tracing.hh中有一组调试宏。它是否生成代码和输出由实际源代码中的宏标志控制: // File: foo.cc #define TRACING 0 #include "tracing.hh" // Away we go . . . TRACEF("debug message"); 标志跟踪应该有一个值;我通常在0和1之间切换 在tracing.h中 #ifdef跟踪将告诉我跟踪已定义 #如果跟踪控制函数宏的定义,如TRACEF() 但如果跟踪没有价值呢?然后#如果跟踪产生错误:
// File: foo.cc
#define TRACING 0
#include "tracing.hh"
// Away we go . . .
TRACEF("debug message");
标志跟踪应该有一个值;我通常在0和1之间切换
在tracing.h中
将告诉我跟踪已定义#ifdef跟踪
控制函数宏的定义,如#如果跟踪
TRACEF()
#如果跟踪产生错误:
In file included from foo.c:3:
tracing.hh:73:12: error: #if with no expression
如何测试跟踪是否已定义但没有值?可能会
#if defined(TRACING) && !TRACING
做这个把戏吗?根据Matti的建议和更多的戳,我认为问题在于:如果跟踪
没有价值,我们需要在测试中使用有效的预处理器表达式#如果…
。这个
表示它必须求值为整数表达式,因此我们需要一个即使缺少其中一个参数也有效的表达式。我最后想到的是:
#if (TRACING + 0)
# . . .
- 如果
跟踪
有一个数值(如#定义跟踪2\n)
,则cpp有一个有效的表达式,并且我们没有更改该值李>
- 如果
跟踪
没有值(如#定义跟踪\n
),预处理器将#If(+0)
计算为false
唯一不能处理的情况是
- 如果
跟踪
具有非数值(即
上的)。cpp手册说,“非宏的标识符……都被认为是数字零”,其计算结果为false
。然而,在这种情况下,考虑这一点是更合理的:<代码>真< /代码>值。唯一做正确事情的是布尔文本true
和false
李>
晚会迟到了,但我发现了一个很好的方法来区分
#define TRACING 0
从
像这样:
#if (0-TRACING-1)==1 && (TRACING+0)!=-2
#error "tracing empty"
#endif
如果跟踪
为空,则表达式的计算结果为0--1
=>1
如果TRACING
为0,则表达式的计算结果为0-0-1
=>-1
我在caseTRACING==-2
中添加了一个额外的检查,这将使第一个测试通过
当然,这对字符串文本不起作用。我想差不多。请参阅下一个答案:不幸的是,这不起作用。您将遇到相同的问题,其中as跟踪将被删除。您将得到类似这样的结果:“#如果定义(跟踪)&&&!”。因此,“error:operator'!'没有正确的操作数”将在生成时引发。您仍然可以通过使用#
运算符将宏设置为字符串来执行运行时测试。C++11可能能够将其转换为编译时测试(我认为使用constexpr
可能是一种方法),但不是预处理器测试。此外,在Visual Studio 2017中,您无法区分空跟踪和跟踪
等于0+0
不是有效的整数表达式。我把它改成了#if(TRACING-0)
,现在它就像一个符咒一样工作。谢谢你指出这一点。我没有测试,但我想我们也可以做-DTRACING=
。
#if (0-TRACING-1)==1 && (TRACING+0)!=-2
#error "tracing empty"
#endif