简体   繁体   English

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

[英]Preprocessor macro expansion to another preprocessor directive

Initially I thought I needed this, but I eventually avoided it. 最初我以为我需要这个,但我最终还是避开了它。 However, my curiosity (and appetite for knowledge, hum) make me ask: 然而,我的好奇心(以及对知识,嗡嗡声的兴趣)让我问:

Can a preprocessor macro, for instance in 可以是预处理器宏,例如

#include "MyClass.h"

INSTANTIATE_FOO_TEMPLATE_CLASS(MyClass)

expand to another include, like in 扩展到另一个包括,像在

#include "MyClass.h"

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

?

I believe that cannot be done, this is because the pre-processor is single pass . 我相信无法做到,这是因为预处理器是单通道 So it cannot emit other preprocessor directives. 所以它不能发出其他预处理器指令。

Specifically, from the C99 Standard (6.10.3.4 paragraph 3): 具体而言,根据C99标准(6.10.3.4第3段):

3 The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one, ... 3生成的完全宏替换的预处理标记序列不会作为预处理指令处理,即使它类似于一个,...

Interestingly enough, This is why the unary _Pragma operator was added to c99. 有趣的是,这就是将一元_Pragma运算符添加到c99的原因。 Because #pragma could not be emited by macros, but _Pragma can. 因为#pragma无法由宏_Pragma ,但_Pragma可以。

The C standard says this about preprocessing directives (C99 - 6.10(2) - Preprocessing directives): C标准说明了预处理指令(C99 - 6.10(2) - 预处理指令):

A preprocessing directive consists of a sequence of preprocessing tokens that begins with a # preprocessing token that (at the start of translation phase 4) ... 预处理指令由一系列预处理令牌组成,这些令牌以#预处理令牌开头(在转换阶段4开始时)......

and (C99 - 6.10(7)): 和(C99 - 6.10(7)):

The preprocessing tokens within a preprocessing directive are not subject to macro expansion unless otherwise stated. 除非另有说明,否则预处理指令中的预处理标记不受宏扩展的影响。

EXAMPLE In: 示例在:

 #define EMPTY EMPTY # include <file.h> 

the sequence of preprocessing tokens on the second line is not a preprocessing directive, because it does not begin with a # at the start of translation phase 4, even though it will do so after the macro EMPTY has been replaced 第二行上的预处理令牌序列不是预处理指令,因为它在转换阶段4开始时不以#开头,即使它在宏EMPTY被替换后也会这样做

So, no, macros cannot expand into a ' #include ' preprocessing directive. 所以,不,宏不能扩展为' #include '预处理指令。 Those directives need to be in place at the start of translation phase 4 (when handling those directives takes place preprocessing happens). 这些指令需要在翻译阶段4的开始处(当处理那些指令发生预处理时)。 Since macro expansion occurs during phase 4, macros can't cause something to exist at the start of phase 4. 由于在阶段4期间发生宏扩展,因此宏不能在阶段4的开始处存在某些东西。

I'd like to point out however, that the following does work: 不过我想指出的是,以下内容确实有效:

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

#include PLATFORM_HEADER

because the C standard says this (C99, 6.10.2(4) - Source file inclusion): 因为C标准说这个(C99,6.10.2(4) - 源文件包含):

A preprocessing directive of the form 表单的预处理指令

 # include pp-tokens new-line 

(that does not match one of the two previous forms) is permitted. (允许与前两种形式中的一种不匹配)。 The preprocessing tokens after include in the directive are processed just as in normal text. 指令中包含的预处理标记的处理方式与普通文本一样。 (Each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens.) (当前定义为宏名称的每个标识符将替换为其预处理标记的替换列表。)

All preprocessor directives are interpreted before macro expansion begins, so no, you cannot have a macro expand into an #include directive and have it be interpreted as such. 在宏扩展开始之前解释所有预处理程序指令,所以不,你不能将宏扩展为#include指令并将其解释为这样。 Instead, it will be interpreted as (erroneous) C++ code. 相反,它将被解释为(错误的)C ++代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM