你想要的是不可能使用标准 C 预处理器。通过阅读 C 标准进行检查,例如n1570,或一些C reference,或wikipage on the C preprocessor,或GNU cpp manual。
但请考虑另一种实现相同目的的方法:适当地配置您的build automation。
例如,如果您使用make,则适当地编辑您的Makefile。如何做到这一点是一个非常不同的问题。
你可以有一个 make 的规则,它将特定的 -DMODULE=name 传递给 gcc
例如,在我的bismon (on github) 中,Makefile 的近线 141 类似于
modules/modbm_%.so: modules/modbm_%.c bismon.h $(GENERATED_HEADERS) $(BM_HEADERS)
$(CCACHE) $(LINK.c) -fPIC \
-DBISMON_MODID=$(patsubst modules/modbm_%.c,_%,$<) -shared $< -o $@
要有创意。构建机制是源代码的一部分。调整它来做你想做的事。不要期望标准预处理器能满足您的所有需求。在command line 上了解如何invoke GCC(或您最喜欢的编译器)。在some cases 中,生成 一些 C 文件(可能是一些头文件)甚至是值得的,您可以使用 另一个 预处理器(如 GPP 或 m4)那个目的。
请记住,编译器(特别是 GCC 和 Clang)是一个命令行程序,您应该从其他东西(如 make、ninja 或许多其他构建自动化工具)驱动它。
(即使在微软系统上,编译器仍然是一个命令行的东西,但这个事实经常被忽略)
顺便说一句,我不喜欢很多IDEs,因为他们隐藏构建过程,你需要掌握它。因此,您需要对其进行配置(例如,通过编写您的 Makefile 或其他内容)并理解和调整它。
主要动机是避免在每个文件的顶部放置#define MODULE,而是在一个定义映射的位置
定义此类映射的单个位置可能应该是您的构建基础架构(例如,如果使用 make,则为您的 Makefile);您将调整它以使用适当的 -DMODULE=name 标志调用 gcc 或 clang(或大多数其他 C 编译器)。 (顺便说一句,您还希望源文件的基本名称是 C 标识符的约定,因此您不会有任何 a-1.c 文件-因为 a-1 不是标识符-,而是bcde.c 一)。
如果使用 GNU make,请阅读其 documentation,然后运行 make -p 以了解与您的案例相关的规则(内置规则和自定义规则)。然后考虑一下类似的规则:
%.o: %.c $(YOURHEADERS)
$(COMPILE.c) -DMODULE=$(patsubst %.c,MODULE_%,$^) -c $< -o $@
但根据您的需要调整该规则。 (如果你的文件名是小写的,并且你想要大写的MODULE,你可能需要一些$(shell ... )。
顺便说一句,您还可以生成您的Makefile 的一部分(或者有一些生成 C 文件,您可以适当地#include)。