测试是否在宏内部定义了预处理器符号 [英] Test if preprocessor symbol is defined inside macro
问题描述
测试预处理器符号是否定义的常用方法是使用#ifdef
.但是,#ifdef
不能在宏中使用.如果该宏的参数是已定义的预处理器符号,我需要一种方法来检查该宏.
The usual way to test whether a preprocessor symbol is defined is using #ifdef
. However, #ifdef
cannot be used in a macro. What I need is a way to check in a macro if an argument of that macro is a defined preprocessor symbol.
例如:
#define TRACE(x,y) if(IS_DEFINED(x)){ std::cout << y; }
这里,TRACE
有两个参数,第一个x
应该是预处理器符号的名称.如果定义了这样的符号,则应打印第二个参数.我正在寻找不存在的 IS_DEFINED
函数/宏.
Here, TRACE
takes two arguments, the first x
should be the name of a preprocessor symbol. If such symbol is defined, the second argument should be printed. The non-existing IS_DEFINED
function/macro is what I am looking for.
用法如下:
#undef BLA
TRACE(BLA,"abc") // "abc" won't be printed, as BLA is not defined
#define BLA 1
TRACE(BLA,"xyz") // "xyz" will be printed, as BLA is a defined symbol
有没有办法做到这一点?也许一些宏观魔术?当然,这些解决方案应该适用于任何符号,而不仅仅是 BLA
或一组硬编码的符号.如果事先知道要检查的符号集,显然很容易.
Is there a way to achieve this? Maybe some macro magic? Of course, thes solution should work for any symbol, not only BLA
or a hardcoded set of symbols. It is obviously quite easy if the set of symbols to be checked is known in advance.
推荐答案
Linux' kgconfig.h
为此用例定义了一个 __is_defined
宏:
#define __ARG_PLACEHOLDER_1 0,
#define __take_second_arg(__ignored, val, ...) val
/*
* Helper macros to use CONFIG_ options in C/CPP expressions. Note that
* these only work with boolean and tristate options.
*/
/*
* Getting something that works in C and CPP for an arg that may or may
* not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1"
* we match on the placeholder define, insert the "0," for arg1 and generate
* the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one).
* When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when
* the last step cherry picks the 2nd arg, we get a zero.
*/
#define __is_defined(x) ___is_defined(x)
#define ___is_defined(val) ____is_defined(__ARG_PLACEHOLDER_##val)
#define ____is_defined(arg1_or_junk) __take_second_arg(arg1_or_junk 1, 0)
它是 C99,适用于三态选项(未定义、定义为 0、定义为 1).
It's C99 and works for tristate options (undefined, defined to 0, defined to 1).
这篇关于测试是否在宏内部定义了预处理器符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!