预处理器宏扩展到另一个预处理器指令

时间:2009-08-11 18:12:36

标签: c++ macros c-preprocessor expansion preprocessor-directive

最初我以为我需要这个,但我最终还是避开了它。然而,我的好奇心(以及对知识,嗡嗡声的兴趣)让我问:

可以预处理器宏,例如在

#include "MyClass.h"

INSTANTIATE_FOO_TEMPLATE_CLASS(MyClass)

扩展到另一个包含,例如

#include "MyClass.h"

#include "FooTemplate.h"
template class FooTemplate<MyClass>;

3 个答案:

答案 0 :(得分:13)

我认为无法做到,这是因为预处理器单次传递。所以它不能发出其他预处理器指令。

具体而言,根据C99标准(6.10.3.4第3段):

  

3结果完全   宏替换的预处理令牌   序列不作为a处理   预处理指令,即使它   类似于......,

有趣的是,这就是将一元_Pragma运算符添加到c99的原因。由于#pragma无法通过宏发出,_Pragma可以。{/ p>

答案 1 :(得分:9)

C标准说明了预处理指令(C99 - 6.10(2) - 预处理指令):

  

预处理指令由一系列以...开头的预处理标记组成   #预处理令牌(在翻译阶段4的开始)   ...

和(C99 - 6.10(7)):

  

预处理指令中的预处理标记不受宏的限制   扩展,除非另有说明。

     

示例:

#define EMPTY
EMPTY # include <file.h>
     

第二行上的预处理令牌序列不是预处理指令,因为它在转换阶段4的开始时不以#开头,即使它在替换宏EMPTY后也会这样做

所以,不,宏不能扩展为'#include'预处理指令。这些指令需要在翻译阶段4的开始处(当处理那些指令发生预处理时)。由于在阶段4期间发生宏扩展,因此宏不能在阶段4的开始处存在某些东西。

但是我想指出,以下可以工作:

#ifdef WIN32
#define PLATFORM_HEADER "platform/windows/platform.h"
#else
#define PLATFORM_HEADER "platform/linux/platform.h"

#include PLATFORM_HEADER

因为C标准说明了这一点(C99,6.10.2(4) - 源文件包含):

  

表单

的预处理指令
# include pp-tokens new-line
     允许使用

(与前两种形式中的一种不匹配)。预处理   指令中包含的标记与正常文本一样处理。 (每   当前定义为宏名称的标识符将替换为其替换列表   预处理令牌。)

答案 2 :(得分:1)

在宏扩展开始之前解释所有预处理程序指令,所以不,你不能将宏扩展为#include指令并将其解释为这样。相反,它将被解释为(错误的)C ++代码。