#包含从宏__file__派生的文件
#include file derived from macro __FILE__?
观察以下程序:
#include __FILE__
main(){}
预处理器陷入了无限递归中,在其内部包含其自身的副本,并抱怨已经定义了main()
。
如果我可以使用宏来包含文件,我可以基于__FILE__
导出文件名并将其包含在内吗?
例如,我想在"foo.cpp"
内部包含"foo.h"
,但从__FILE__
派生。
##
将连接宏- 也可以对宏进行字符串化
可以用预处理器完成吗?
C标准规定了#include
:的三种形式
#include <file>
#include "file"
#include ANYTHING ELSE
在前两种情况下,没有发生宏观扩展,因此没有办法改变行为。在第三种情况下,C99说(§6.10.2p4):
指令中
#include
之后的预处理标记为[宏扩展]。所有替换后产生的指令应与前两种形式中的一种匹配[脚注:注意,相邻的字符串文字不会连接到单个字符串文字中]。在<并且实现定义了一个>预处理令牌对或一对"字符组合成单个标题名称"预处理令牌
C++98§16.2p4中的措辞略有不同,但实际上相当。
任何带有"shall"的句子都提出了一个硬性要求:在这种情况下,如果ANYTHING ELSE
扩展到除以<
开始并以>
结束或以"
开始并以其结束的一系列标记之外的任何内容,则程序就是格式错误的。该令牌序列的确切解释是由实现定义的,但请注意,脚注特别禁止字符串文字串联。
因此,由于__FILE__
的扩展是一个字符串常量,在#include
中使用它的唯一方法是
#include __FILE__
正如你所发现的,这会导致无限递归,以及
#define LT <
#define GT >
#include LT __FILE__ etc GT
这对我可以方便地测试的所有编译器都有有趣但无用的影响。假设上面是在一个名为test.c
:的文件中
- GCC试图打开一个名为
"test.c" etc
的文件,其中包含引号和空格 - clang更符合字面意思,它查找相同的文件名,但带有前导和尾随空格
- MSVC宏仅扩展
LT
(我认为这是一致性冲突),抱怨没有匹配的>
,然后尝试打开名为__FILE__ etc GT
的文件
(GCC的行为记录在这里;你可以自己做任何其他事情。)
tl;博士:在预处理器内部没有办法做你想做的事情。我建议您计算出构建系统中要包含的文件的名称,并用-D
开关通知编译器(在Unixy系统上,您需要双引号-DINCLUDEME='"includeme.h"'
;我不会说CMD)
我想出的最好的办法是:
#define foo(x) #x
#include foo(x)
prog.cpp:2:16:错误:x:没有这样的文件或目录
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- 如何使用单独文件中的派生类访问友元函数对象
- 快速傅立叶变换:使用模板化派生类'undefined reference'即使标头和.cpp文件匹配也会出错
- 没有实现文件(.cpp)的派生类
- 将派生类成员写入二进制文件
- #包含从宏__file__派生的文件
- 在派生类中的CPP文件中定义模板和定义
- 派生后在父级中创建的子级文件写入描述符
- 派生类是否C++必须在头文件中包含继承函数/成员的定义
- C++:具有硬编码派生类的 ADT 基类与从文件输入构建的包罗万象的类
- 枚举可执行文件C++派生类
- Windows 中的 C++:头文件更改后,仅编译派生类或不编译
- 不同文件c++中的派生类
- 派生类的头文件中声明的字符串在超级类中为null
- 继承问题:在派生类中使用基类的头文件和默认构造函数
- 派生自库中的std::exception:仅头文件解决方案是否适用于捕获异常
- *.h文件和*.cpp文件中派生类的定义和声明
- 如何定义派生类的非成员构造函数(在类头文件中)