是否可以使用预处理器 __file__ 在 C 中生成 #define?
is it possible to use the preprocessor __file__ to generate a #define in C?
为了提高某些代码的美感,我希望 .h 文件包含一些代码,这些代码根据包含 .h 文件的文件设置#define。例如
#if (__file__ == "main.c")
#define MOUDLE MODULE_MAIN
#elif (__file__ == "foo.c")
#define MODULE MODULE_FOO
#endif
有什么办法可以完成这样的事情吗?主要动机是避免将 #define MODULE 放在每个文件的顶部,而是有一个定义映射的位置,并且只包含相同的 .h 文件。
不,你不能这样做。 #if
只能做整数表达式。它对字符串一无所知,也不知道如何比较它们。
标准 C 预处理器不可能满足您的需求。通过阅读 C 标准进行检查,例如 n1570, or some C reference, or the wikipage on the C preprocessor, or the GNU cpp
manual.
但请考虑另一种实现相同目的的方法:适当地 配置您的 build automation.
例如,如果您使用 make
,则适当编辑您的 Makefile
。如何做到这一点是一个非常不同的问题。
您可以为 make
设置一个规则,将特定的 -DMODULE=
name 传递给 gcc
例如在我的 bismon
(on github) the Makefile
has near line 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 $@
要有创意。构建机器是源代码的一部分。适应它做你想做的事。不要指望标准预处理器能够满足您的所有需求。了解如何 invoke GCC (or your favorite compiler) on the command line. In , it is even worthwhile to generate some C file (perhaps some header file), and you might use another preprocessor (like GPP 或 m4) 为此目的。
记住编译器(特别是 GCC 和 Clang)是一个命令行程序,你应该从其他东西(比如make
、ninja
或许多其他构建自动化工具)。
(即使在微软系统上,编译器仍然是命令行的东西,但这个事实经常被忽略)
顺便说一句,我不喜欢很多IDE,因为它们隐藏构建过程,你需要掌握它。所以你需要配置它(例如,通过写你的 Makefile
或其他东西)并理解和定制它。
The main motivation is to avoid putting a #define MODULE
at the top of every file and instead have one location where the mapping is defined
定义此类映射的单个位置可能应该是您的构建基础结构(例如,您的 Makefile
如果使用 make
);您将调整它以使用适当的 -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 $@
但根据您的需要调整该规则。 (如果你的文件名是小写的,你可能需要一些 $(shell
... )
在里面,而你想要大写 MODULE
)。
顺便说一句,您还可以生成 Makefile
的一部分(或者有一些 生成的 C 文件,您可以适当地 #include
)。
为了提高某些代码的美感,我希望 .h 文件包含一些代码,这些代码根据包含 .h 文件的文件设置#define。例如
#if (__file__ == "main.c")
#define MOUDLE MODULE_MAIN
#elif (__file__ == "foo.c")
#define MODULE MODULE_FOO
#endif
有什么办法可以完成这样的事情吗?主要动机是避免将 #define MODULE 放在每个文件的顶部,而是有一个定义映射的位置,并且只包含相同的 .h 文件。
不,你不能这样做。 #if
只能做整数表达式。它对字符串一无所知,也不知道如何比较它们。
标准 C 预处理器不可能满足您的需求。通过阅读 C 标准进行检查,例如 n1570, or some C reference, or the wikipage on the C preprocessor, or the GNU cpp
manual.
但请考虑另一种实现相同目的的方法:适当地 配置您的 build automation.
例如,如果您使用 make
,则适当编辑您的 Makefile
。如何做到这一点是一个非常不同的问题。
您可以为 make
设置一个规则,将特定的 -DMODULE=
name 传递给 gcc
例如在我的 bismon
(on github) the Makefile
has near line 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 $@
要有创意。构建机器是源代码的一部分。适应它做你想做的事。不要指望标准预处理器能够满足您的所有需求。了解如何 invoke GCC (or your favorite compiler) on the command line. In
记住编译器(特别是 GCC 和 Clang)是一个命令行程序,你应该从其他东西(比如make
、ninja
或许多其他构建自动化工具)。
(即使在微软系统上,编译器仍然是命令行的东西,但这个事实经常被忽略)
顺便说一句,我不喜欢很多IDE,因为它们隐藏构建过程,你需要掌握它。所以你需要配置它(例如,通过写你的 Makefile
或其他东西)并理解和定制它。
The main motivation is to avoid putting a
#define MODULE
at the top of every file and instead have one location where the mapping is defined
定义此类映射的单个位置可能应该是您的构建基础结构(例如,您的 Makefile
如果使用 make
);您将调整它以使用适当的 -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 $@
但根据您的需要调整该规则。 (如果你的文件名是小写的,你可能需要一些 $(shell
... )
在里面,而你想要大写 MODULE
)。
顺便说一句,您还可以生成 Makefile
的一部分(或者有一些 生成的 C 文件,您可以适当地 #include
)。