Preprocessor macro expansion to another preprocessor directive

回眸只為那壹抹淺笑 提交于 2019-11-27 16:33:16

问题


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>;

?


回答1:


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):

3 The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one, ...

Interestingly enough, This is why the unary _Pragma operator was added to c99. Because #pragma could not be emited by macros, but _Pragma can.




回答2:


The C standard says this about preprocessing directives (C99 - 6.10(2) - Preprocessing directives):

A preprocessing directive consists of a sequence of preprocessing tokens that begins with a # preprocessing token that (at the start of translation phase 4) ...

and (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

So, no, macros cannot expand into a '#include' preprocessing directive. Those directives need to be in place at the start of translation phase 4 (when handling those directives takes place preprocessing happens). Since macro expansion occurs during phase 4, macros can't cause something to exist at the start of phase 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):

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.)




回答3:


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. Instead, it will be interpreted as (erroneous) C++ code.



来源:https://stackoverflow.com/questions/1262063/preprocessor-macro-expansion-to-another-preprocessor-directive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!