Question

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

?

Was it helpful?

Solution

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.

OTHER TIPS

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top