You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过宏生成的文件名实现#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)

原理说明

  1. #操作符会把宏参数转换成字符串字面量,比如#MyClass变成"MyClass",#h变成"h";
  2. C语言中相邻的字符串字面量会自动合并,所以"MyClass" "." "h"会被编译器处理成"MyClass.h";
  3. 用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 00:55:15