如何在C预处理器中使用复杂的控制流,算术或函数原语?

时间:2013-02-13 16:12:21

标签: c c-preprocessor

我希望能够使用更完善的语言编写预处理器宏。理想情况下,这种语言应包括以下功能:

  • 布尔和自然算术和比较
  • 基于比较的分支
  • 列表表示
  • 递归
  • 变量绑定
  • 用作第一类值和更高阶函数
  • 部分功能应用和currying
  • 功能原语,例如mapfold
  • 用于常见代码生成任务的有用功能/结构

这可以在C预处理器中实现吗?

1 个答案:

答案 0 :(得分:3)

令人难以置信的是,答案是肯定的! Order仅头文件库提供了一组宏,这些宏在C预处理器中实现了一种函数语言。它包括所有指定的功能等。只要您的C预处理器几乎完全符合C99标准,您就可以使用它。 GNU CPP(在GCC和G ++中使用)与Boost Wave预处理器兼容。订单自2004年以来一直存在。虽然订单已不再维护,但如果没有完整记录,它的功能非常全面。

以下是使用Order的简单示例:

#define AVERAGE(...) ((ORDER_PP( \
    8seq_for_each_with_delimiter( \
    8put, \
    8emit(8quote(+)), \
    8tuple_to_seq(8quote((__VA_ARGS__)))))) / \
    ORDER_PP(8to_lit(8tuple_size(8quote((__VA_ARGS__))))))

AVERAGE扩展为表达所提供参数的平均值的表达式。 AVERAGE(a, b, c)(例如)扩展为((a + b + c) / 3)。这是一个非常简单的示例,它不使用Order的所有功能。

另一个简单的例子,显示使用预编译算法(使用任意精度自然数表示),作为第一类值(参见8plus的使用)和变量绑定,是一个用于计算的宏(整数算术)预处理器中的平均值:

#define AVERAGE_LITERAL(...) ORDER_PP(\
    8let((8A, 8quote((__VA_ARGS__))), \
    8to_lit(8quotient( \
    8seq_fold(8plus, 0, 8tuple_to_seq(8A)), \
    8tuple_size(8A)))))

AVERAGE_LITERAL(5, 6, 8, 9)扩展为7

我只涉及了一些功能。随附的文档和教程中提供了更多实际示例,包括显示Order如何帮助删除几乎所有繁琐的代码重复的示例。

顺序非常强大,它仍然与C ++程序员非常相关 - 模板和内联只能解决一些问题。订单解决了大多数其他问题。我能找到的唯一固有限制是无法操纵字符串文字或以替换或连接之外的任何方式操作令牌,因为这是由C预处理器强加的。