Observe the following program:
#include __FILE__
main(){}
The preprocessor gets stuck in infinite recursion including a copy of itself inside itself and complaining about main()
already being defined.
If I can use macros to include files,
can I derive a file name based on __FILE__
and include it?
For example, I'd like to include "foo.h"
whilst inside "foo.cpp"
, but derive it from __FILE__
.
##
will concatenate macros. Can it be done with the preprocessor?
The C standard specifies three forms of #include
:
#include <file>
#include "file"
#include ANYTHING ELSE
In the former two cases, no macro expansion takes place, so there's no way to vary the behavior. In the third case, C99 says (§6.10.2p4):
The preprocessing tokens after
#include
in the directive are [macro-expanded]. The directive resulting after all replacements shall match one of the two previous forms [footnote: Note that adjacent string literals are not concatenated into a single string literal]. The method by which a sequence of preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into a single header name preprocessing token is implementation-defined.
Slightly different, but effectively equivalent, wording appears in C++98 §16.2p4.
Any sentence with "shall" in it imposes a hard requirement: in this case, the program is ill-formed if ANYTHING ELSE
expands to anything but a sequence of tokens beginning with <
and ending with >
, or beginning and ending with "
. The exact interpretation of that sequence of tokens is implementation defined, but note that the footnote specifically forbids string-literal concatenation.
So, as the expansion of __FILE__
is a string constant, the only ways to use it in an #include
are
#include __FILE__
which, as you discovered, leads to infinite recursion, and
#define LT <
#define GT >
#include LT __FILE__ etc GT
which has amusing, but useless, effects on all the compilers I can conveniently test. Assuming that the above is in a file named test.c
:
"test.c" etc
, with the quotation marks and space included verbatim.LT
(it is my considered opinion that this is a conformance violation), complains that there is no matching >
, and then attempts to open a file named __FILE__ etc GT
.(GCC's behavior is documented here; you are on your own for anything else.)
tl;dr: There is no way to do what you want from inside the preprocessor. I recommend working out the name of the file-to-be-included from your build system and notifying the compiler of it with a -D
switch (on a Unixy system you will need double quotation, -DINCLUDEME='"includeme.h"'
; I don't speak CMD)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With