【问题标题】:MASK(...) macro with undefined number of arguments (in C)具有未定义数量的参数的 MASK(...) 宏(在 C 中)
【发布时间】:2013-01-09 14:38:06
【问题描述】:

(抱歉英语不好。)

我需要宏 MASK 这样:

  • MASK(a) 扩展为 (1<<(a))
  • MASK(a,b) 扩展为 (1<<(a) | 1<<(b))
  • MASK(a,b,c) 扩展为 (1<<(a) | 1<<(b) | 1<<(c))

是否可以在 C 预处理器中定义这样的宏?也许可以帮助一些 GCC 扩展?或者也许可以用单个参数实现MASK(x),使得MASK((a,b)) 扩展为(1<<(a) | 1<<(b)),等等。

已添加。我对将MASK 实现为函数不感兴趣。

【问题讨论】:

  • 您是否要求宏完全以这种方式扩展(换句话说,它会生成一个常量),或者如果扩展为函数调用是否可以?后者可以使用 C99 可变参数宏来完成。
  • @Chris:我知道我可以使用...MASK 实现为内联函数。此外,我认为像 GCC 这样的优秀编译器会优化调用,因为它会明确写成(1<<(a))|...。所以,我只对 preprocessor 感兴趣。

标签: gcc c-preprocessor


【解决方案1】:

是的,假设一个几乎完全符合 C99 的预处理器,例如 GNU CPP(由 GCC/G++ 使用),这是可能的,无需任何扩展。

这里有一些使用出色的Order 库的不同解决方案。您需要添加 #include <order/interpreter.h> 才能使用它们。

只有一个#define

#define MASK(...) (ORDER_PP(8seq_for_each_with_delimiter( \
    8fn(8N, 8print((1<<) 8tuple(8N))), \
    8emit(8quote(|)), \
    8tuple_to_seq(8quote((__VA_ARGS__))))))

为了编译速度和可维护性:

#define GEN_MASK(x) 1<<(x)
#define ORDER_PP_DEF_8mask ORDER_PP_FN(8fn(8N, \
    8emit(8quote(GEN_MASK),8tuple(8N))))
#define MASK(...) (ORDER_PP(\
    8seq_for_each_with_delimiter(8mask, 8emit(8quote(|)), \
    8tuple_to_seq(8quote((__VA_ARGS__))))))

对类似问题使用泛化:

#define MAP_DELIMITED(f,d, ...) ORDER_PP(\
    8seq_for_each_with_delimiter(f, \
    8emit(8quote(d)), \
    8tuple_to_seq(8quote((__VA_ARGS__)))))
#define MASK(...) (MAP_DELIMITED( \
    8fn(8N, 8print((1<<) 8tuple(8N))), \
    |, \
    __VA_ARGS__))

Order 实际上在预处理器中实现了一种高级函数式语言,允许使用比您想象的要复杂得多的宏。上述链接中的 repo 包含许多示例和文档的来源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-14
    • 2011-07-14
    • 2014-11-25
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多