测试是否在宏内部定义了预处理器符号 [英] Test if preprocessor symbol is defined inside macro

查看:13
本文介绍了测试是否在宏内部定义了预处理器符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

测试预处理器符号是否定义的常用方法是使用#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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆