为了改善某些代码的美观,我希望.h文件包含一些代码,根据包含.h文件的文件设置#define。例如
#if (__file__ == "main.c")
#define MOUDLE MODULE_MAIN
#elif (__file__ == "foo.c")
#define MODULE MODULE_FOO
#endif
有没有办法完成这样的事情?主要动机是避免将#define MODULE放在每个文件的顶部,而是将一个位置定义为映射,并且只包含相同的.h文件。
答案 0 :(得分:3)
不,你不能这样做。 #if
只能执行整数表达式。它对字符串或如何比较字符串一无所知。
答案 1 :(得分:1)
使用标准C预处理器,您想要的是不可能。通过阅读C标准进行检查,例如n1570,或C reference,wikipage on the C preprocessor或GNU cpp
manual。
但请考虑另一种实现相同目的的方法:正确配置 build automation。
例如,如果您使用make
,请相应地修改Makefile
。如何做到这一点是一个非常不同的问题。
您可以拥有make
的规则,该规则会将特定的-DMODULE=
名称传递给gcc
例如,在bismon
(on github) Makefile
141附近有invoke GCC类似于
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上了解如何some cases(或您最喜欢的编译器)。在GPP中,生成某些C文件(可能是某个头文件)甚至是值得的,您可以使用另一个预处理器(如GCC或m4)为此目的。
请记住,编译器(特别是Clang和make
)是一个命令行程序,你应该从其他东西开始(比如ninja
,IDE或许多其他程序构建自动化工具)。
(即使在微软系统上,编译器仍然是命令行,但这个事实经常被忽略)
顺便说一句,我不喜欢很多documentation因为他们隐藏构建过程,你需要掌握它。因此,您需要对其进行配置(例如,通过编写Makefile
或其他内容)并理解和定制它。
主要动机是避免在每个文件的顶部放置
#define MODULE
,而是在一个位置定义映射
定义此类映射的单个位置应该是您的构建基础结构(例如,如果使用Makefile
,则为make
);您将使用适当的gcc
名称标记来调整clang
或-DMODULE=
(或大多数其他C编译器)。 (顺便说一句,您还希望约定您的源文件的基本名称是C标识符,因此您不会拥有任何a-1.c
文件 - 因为a-1
不是标识符 - 但bcde.c
一个。)
如果使用GNU make
,请阅读其https://laravel.com/docs/5.6/mix,然后运行make -p
以了解与您的案例相关的规则(内置和自定义)。然后考虑一个类似于以下规则:
%.o: %.c $(YOURHEADERS)
$(COMPILE.c) -DMODULE=$(patsubst %.c,MODULE_%,$^) -c $< -o $@
但根据您的需求调整该规则。 (如果你的文件名是小写的,你可能需要一些$(shell
... )
,并且你想要大写MODULE
)。
Makefile
(或者有一些生成的 C文件,你可以适当地#include
。