C标准规定了三种形式的#include
:
#include <file>
#include "file"
#include ANYTHING ELSE
指令中 #include 后的预处理标记 [将被宏扩展]。所有替换后的指令必须与之前两种形式之一匹配[脚注:注意相邻的字符串字面量不会连接成单个字符串字面量]。在 < 和 > 预处理标记对或一对 " 字符之间的预处理标记序列如何组合成单个头文件名预处理标记的方法是实现定义的。
C++98 §16.2p4 中出现了略有不同但实质上等效的措辞。ANYTHING ELSE
扩展为除以以 <
开头且以 >
结尾或以 "
开头和结尾的标记序列之外的任何内容,则程序是非法的。该标记序列的确切解释是实现定义的,但请注意,脚注明确禁止字符串字面量的连接。__FILE__
的扩展是一个字符串常量,使用它在#include
中的唯一方式是:#include __FILE__
正如您发现的那样,这会导致无限递归。
#define LT <
#define GT >
#include LT __FILE__ etc GT
这会对我方便测试的所有编译器产生有趣但无用的影响。假设以上内容在名为test.c
的文件中:
"test.c" etc
的文件,引号和空格原样包含。LT
宏(我认为这是一种合规违规行为),抱怨没有匹配的>
,然后尝试打开名为__FILE__ etc GT
的文件。(GCC的行为在此处有说明;其他情况需要自行解决。)
tl;dr:无法在预处理器内部完成您想要的操作。 我建议从构建系统中找出要包含的文件名称,并使用-D
开关通知编译器(在类Unix系统上,您将需要双引号,-DINCLUDEME='"includeme.h"'
;我不会CMD)。
#define foo(x) #x
#include foo(x)
prog.cpp:2:16: 错误:x:没有那个文件或目录
__FILE__
。 - Jonathan Leffler