【问题标题】:macro expansion order with included files包含文件的宏扩展顺序
【发布时间】:2013-06-13 08:08:01
【问题描述】:

假设我在包含文件中有一个宏:

// a.h
#define VALUE SUBSTITUTE

还有另一个包含它的文件:

// b.h
#define SUBSTITUTE 3
#include "a.h"

是 VALUE 现在定义为 SUBSTITUTE 并且将在两次传递中宏扩展为 3,还是 VALUE 已设置为 SUBSTITUTE 的宏扩展值(即 3)?

我问这个问题是为了了解 Boost 预处理器库以及它的 BOOST_PP_SLOT 如何定义工作(编辑:我的意思是基础工作)。因此,当我提出上述问题时,如果有人能解释一下,我也很感兴趣。

(我想我也想知道到底在哪里可以找到“涂成蓝色”的规则……)

【问题讨论】:

    标签: c-preprocessor boost-preprocessor


    【解决方案1】:

    VALUE 定义为SUBSTITUTEVALUE 的定义在任何时候都不知道SUBSTITUTE 也已被定义。替换VALUE 后,将再次扫描它所替换的任何内容,然后可能会应用更多替换。所有defines都存在于自己的概念空间中,完全不知道彼此;它们在主程序文本中的扩展位置相互交互(defines 是指令,因此不是程序本身的一部分)。

    预处理器的规则与语言标准中的 C 规则一起指定。标准文件本身要花钱,但你通常可以免费下载“终稿”;最新的(C11)可以在这里找到:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

    对于家庭使用,草稿几乎等同于真实物品。大多数引用该标准的人实际上是在查看草案的副本。 (当然,它比任何现实世界的 C 编译器都更接近实际标准......)

    在 GCC 手册中有更容易理解的宏规则描述:http://gcc.gnu.org/onlinedocs/cpp/Self_002dReferential-Macros.html


    另外...关于 Boost 预处理器库,我不能告诉你太多,但没有使用过它,但有一对漂亮的库,由同一作者称为 Order and Chaos,它们非常“干净”(作为宏代码去)并且易于理解。它们在语气上更具学术性,旨在纯粹而不是便携;这可能让它们更容易阅读。

    (因为我不知道 Boost PP,所以我不知道这与您的问题有多大关系但是)还有一个很好的介绍性示例,介绍了这些库用于高级元编程的技术的孩子在这个答案中构造:Is the C99 preprocessor Turing complete?

    【讨论】:

    • 有道理。我最初的印象是#includes 不知何故有特殊考虑。一段时间以来,我一直是模板元编程的狂热用户,最近才对 PP 感兴趣。实际上,我阅读了您之前链接到的帖子,并直接复制粘贴了示例,却发现它在我的 GCC 或 MSVC 版本下不起作用(据报道,无论如何__VA_ARGS__ 扩展已被破坏,但是即使重复应用#define EXPAND(...) __VA_ARGS__ 解决方法,它也无法工作)。我想这是另一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多