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

moa*_*ala 8 c++ macros expansion c-preprocessor preprocessor-directive

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

可以是预处理器宏,例如

#include "MyClass.h"

INSTANTIATE_FOO_TEMPLATE_CLASS(MyClass)
Run Code Online (Sandbox Code Playgroud)

扩展到另一个包括,像在

#include "MyClass.h"

#include "FooTemplate.h"
template class FooTemplate<MyClass>;
Run Code Online (Sandbox Code Playgroud)

Eva*_*ran 14

我相信无法做到,这是因为预处理器是单通道.所以它不能发出其他预处理器指令.

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

3生成的完全宏替换的预处理标记序列不会作为预处理指令处理,即使它类似于一个,...

有趣的是,这就是将一元运算_Pragma符添加到c99的原因.因为#pragma无法通过宏发出,但_Pragma可以.


Mic*_*urr 10

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

预处理指令由一系列预处理令牌组成,这些令牌以#预处理令牌开头(在转换阶段4开始时)......

和(C99 - 6.10(7)):

除非另有说明,否则预处理指令中的预处理标记不受宏扩展的影响.

示例在:

#define EMPTY
EMPTY # include <file.h>
Run Code Online (Sandbox Code Playgroud)

第二行上的预处理令牌序列不是预处理指令,因为它在转换阶段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
Run Code Online (Sandbox Code Playgroud)

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

表单的预处理指令

# include pp-tokens new-line
Run Code Online (Sandbox Code Playgroud)

(允许与前两种形式中的一种不匹配).指令中包含的预处理标记的处理方式与普通文本一样.(当前定义为宏名称的每个标识符将替换为其预处理标记的替换列表.)