C 预处理器 (CPP) 常被误解为简单的文本到文本的转换器。实际上,C 标准将其定义为一系列将源代码转换为 C 标记流的阶段。虽然许多实现提供文本输出以提高可见性,但其底层机制旨在为 C 解析器准备翻译单元。David Priver 在开发自己的 C2Y 编译器和解释器时,实现了一个自定义的 CPP,并引入了若干扩展,使预处理器更具表现力且更易于调试。

这些扩展的主要目标之一是减少对“预处理器滥用”的需求——即为了模拟标准 CPP 缺乏的功能而使用的复杂、嵌套的宏定义。例如,Priver 引入了 `__print(...)` 和 `__where()` 作为内置调试宏。`__print()` 会展开其参数并直接将其写入 stderr,允许开发者在不转储整个翻译单元的情况下,准确看到宏展开后的内容。`__where()` 则用于识别宏定义的特定文件和行号,解决了在大规模代码库中追踪模糊展开的常见问题。

为了处理列表转换,Priver 添加了 `__map(macro, ...)` 内置函数。在标准 C 中,对序列中的每个参数应用转换通常需要递归函数式宏,而 C 标准通过抑制展开来限制此类操作。虽然开发者可以通过手动循环来“伪造”递归,但这往往速度较慢且视觉上非常混乱。`__map()` 内置函数通过执行线性扫描,将提供的宏应用于每个参数一次,从而简化了这一过程。此外,他还包含了一个 `__VA_COUNT__` 内置函数来简化变长宏的处理,允许开发者直接获取参数数量,而无需依赖复杂的手动计数技术。这些新增功能旨在通过提供对常见元编程模式的原生支持,使预处理器成为一个更强大、更易读的工具。