如何通过宏生成的文件名实现#include引入
问题描述
我定义了如下宏:
#define MY_CLASS MyClass
想要编写一个宏,利用MY_CLASS展开成:
#include "MyClass.h"
我尝试了以下代码:
#define MY_CLASS MyClass #define FILE_EXT h #define M_CONC(A, B) M_CONC_(A, B) #define M_CONC_(A, B) A##B #define APP_BUILD M_CONC(MY_CLASS, M_CONC(.,FILE_EXT)) #include APP_BUILD
但运行后出现3条错误:
Expected "FILENAME" or <FILENAME> Pasting formed '.h', an invalid preprocessing token Pasting formed 'MyClass.', an invalid preprocessing token
有没有可行的实现方法?
可行实现方法
问题出在你用##(token粘贴操作符)拼接了.和h、MyClass和.——C预处理器的token粘贴只能拼接合法的预处理token,.单独不是合法token,直接拼接会触发非法token错误,而且#include要求的是字符串字面量或尖括号包裹的文件名,宏展开后得直接生成这种形式才行。
可以用**字符串化操作符#**配合间接宏展开来实现:
#define MY_CLASS MyClass #define FILE_EXT h // 拼接标识符并字符串化,利用字符串自动拼接特性 #define MAKE_INCLUDE_NAME(CLASS, EXT) #CLASS "." #EXT // 间接调用,确保CLASS和EXT先替换为实际值再字符串化 #define INCLUDE_CLASS(CLASS, EXT) MAKE_INCLUDE_NAME(CLASS, EXT) // 最终使用 #include INCLUDE_CLASS(MY_CLASS, FILE_EXT)
原理说明
#操作符会把宏参数转换成字符串字面量,比如#MyClass变成"MyClass",#h变成"h";- C语言中相邻的字符串字面量会自动合并,所以
"MyClass" "." "h"会被编译器处理成"MyClass.h"; - 用
INCLUDE_CLASS间接调用是关键:如果直接用MAKE_INCLUDE_NAME(MY_CLASS, FILE_EXT),会得到"MY_CLASS" "." "FILE_EXT",而间接调用能先把MY_CLASS和FILE_EXT展开成实际值,再进行字符串化。
如果只需要针对MY_CLASS固定生成.h文件,还可以简化写法:
#define MY_CLASS MyClass #define STRINGIFY(x) #x #define INCLUDE_CLASS(x) STRINGIFY(x.h) #include INCLUDE_CLASS(MY_CLASS)
这里INCLUDE_CLASS(MY_CLASS)会先把MY_CLASS展开为MyClass,再变成MyClass.h,最后字符串化得到"MyClass.h",完全符合#include的要求。
内容的提问来源于stack exchange,提问作者traveh
相关产品推荐
相关产品推荐

