【问题标题】:How to test if a macro identifier is defined without using #ifdef? [duplicate]如何在不使用#ifdef 的情况下测试是否定义了宏标识符? [复制]
【发布时间】:2021-03-09 12:46:05
【问题描述】:

有谁知道如何创建一个可变参数宏,如果它的参数不是定义的宏,则扩展为 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__ 的处理方式非常不同。

【问题讨论】:

  • #if defined(JOE)?
  • 我的意思是我不明白为什么,但是如果您想使用可变参数宏而不是 #ifdef#if defined() 您可以使用更强大的预处理器(例如 m4)来创建可以具有#ifdef 也许在其中。不过好像有点过分了。您是否有任何具体原因需要这样做,所以也许更容易找到解决方案?

标签: c c-preprocessor metaprogramming variadic-macros p99


【解决方案1】:

您可以检查是否使用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 中的进一步使用而不是预处理器。它也不会按照您的意愿评估第二种可能性(如示例所示)。

【讨论】:

  • 这是一个很好的技巧@Leander(我知道),但不幸的是我在预编译时需要01
  • @DavidRanieri 不,我需要一个逻辑标识才能为除NUL 之外的所有可能的字符值获取 1。如果您只关心逻辑值,您也可以将否定排除在外。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2010-09-30
  • 2014-11-23
  • 1970-01-01
  • 2011-11-26
相关资源
最近更新 更多