如何在不使用#ifdef 的情况下测试是否定义了宏标识符?

问题描述

有谁知道如何,或者甚至有可能创建一个可变参数宏,如果它的参数不是定义的宏,则扩展为 0,但如果它的参数是定义的宏,则扩展为 1? (我使用的是 c99。)

#define BOB
#define SUE 45
#define IS_DEFINED(...) ???
IS_DEFINED(JOE)  <---- expands to 0
IS_DEFINED(BOB)  <---- expands to 1 (it's okay if this one doesn't work)
IS_DEFINED(SUE)  <---- expands to 1

编辑:我特别不想要任何与 #if 相关的解决方案......它需要是一个可变参数宏(如果可能的话)所以我可以做这样的事情:

#define CAT_(x,y) x ## y
#define CAT(x,y) CAT_(x,y)
#define CLEANUP0(...) ABC  <--- treats __VA_ARGS__ one way
#define CLEANUP1(...) XYZ  <--- treats __VA_ARGS__ a different way
#define CLEANUP(...) CAT(CLEANUP,IS_DEFINED(DEFAULT))(__VA_ARGS__)

其中 ABCXYZ 是其他扩展的占位符,它们以非常不同的方式对待 __VA_ARGS__

解决方法

您可以检查是否使用 defined() 定义了宏,但是这只适用于 #ifdef 工作的相同情况(据我所知)。我不认为这是可能的,但我可能错了。

编辑:

我不知道这是否对你想要的有帮助,因为结果不会是一个常量表达式。但是,如果您愿意,可以定义以下宏:

#define _IS_DEFINED(...) (!!*#__VA_ARGS__)
#define IS_DEFINED(...) _IS_DEFINED(__VA_ARGS__)
#define BOB

如果我们现在评估这个,我们会得到

int main() {
        printf("%d\n",IS_DEFINED(BOB));
}

这会给我们

0

这是因为 IS_DEFINED(BOB) 扩展为 (!!*"")。在这种情况下,"" 只是一个指向 .data 部分中某个 NUL 字节的指针,取消引用它会产生 0。但同样,这不是一个常量表达式,因此该值只能用于在 C 中进一步使用,而不是预处理器。它也不会根据您的需要评估第二种可能性(如示例所示)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...