【发布时间】:2020-01-01 14:22:33
【问题描述】:
对于 C99 代码库,我非常依赖宏来代替适当的 C++ 模板。对于我的用例,宏最严重的缺点是很难/不可能调试生成的代码,这很多。如果我可以创建一个自定义预处理器,该预处理器仅将一组白名单宏扩展为中间构建步骤,那就太好了。我想知道是否可以使用 Boost 库中的 Wave 预处理器来做到这一点。我正在浏览文档,但老实说,我还不清楚这是否可能。
1) 从概念上讲,我想实现以下目标:
foo.c => selective_wave_preprocessor(MACRO_BAR, MACRO_BAZ) => foo.c_preprocessed
所以在这种情况下,foo.c_preprocessed 将是 ONLY 在foo.c 中扩展(类似函数)宏的MACRO_BAR 和MACRO_BAZ 的结果。如果我在foo.c 和foo.c_preprocessed 上运行普通的预处理器,那么输出必须是相同的。
2) 我希望看到标记为白名单的多行宏实际上是用换行符格式化的,这样它仍然是人类可读的。
我希望有人能告诉我 Wave 预处理器是否是执行此操作的正确工具。如果是这样,我会很高兴看到一个关于如何执行此类操作的示例,或者为我指出完成此操作所需的正确 Wave 原语。
【问题讨论】:
-
请注意,§5.1.1.2 Translation phases 将反斜杠换行符删除列为第 2 阶段,因此预处理器本身不会在宏定义中的反斜杠之后看到嵌入的换行符。这使得“保留换行符”变得困难。这也是为什么 X11
imake程序使用@@来标记换行符的原因;它对来自 C 预处理器的输出进行后处理,以将@@转换回换行符。我不知道其余问题的答案;我没有玩过 Wave。 -
我也不知道 Wave,但是通过它的一些文档的简短浏览表明,它提供的独立 C++ 预处理器没有运行时配置选项,可以避免执行宏扩展符合标准的预处理器将执行。但是,可以使用 Wave 类来构建您自己的自定义预处理器。
-
@JonathanLeffler 啊,请原谅我对精确编译步骤的了解不足。因此,如果我的评论正确,我的问题需要一个专门的词法分析器来执行例如
@@替换技巧,以便我的预处理器应该忽略 do 标记,并且“后预处理器”可以将这些@@替换回换行符? -
或多或少 — 这意味着您使用的任何预处理器技术都可能需要非标准的词法分析。请记住,预处理器的行为“好像”遵循标准中概述的阶段。标准本身说这些步骤通常是结合在一起的。诸如 GCC 之类的编译器确实会报告导致问题的代码;它将指向一个语句中的一个源代码行,该语句是用反斜杠换行符延续的多行编写的。您想要的可能可以完成,但可能需要对标准预处理器技术进行相当大的调整。 Wave 可能是一个好的开始。
标签: c++ c boost c-preprocessor