【问题标题】:is it possible to use the preprocessor __file__ to generate a #define in C?是否可以使用预处理器 __file__ 在 C 中生成#define?
【发布时间】:2018-09-30 08:12:12
【问题描述】:

为了提高某些代码的美感,我希望 .h 文件包含一些代码,这些代码根据包含 .h 文件的文件设置#define。例如

#if (__file__ == "main.c")
#define MOUDLE MODULE_MAIN
#elif (__file__ == "foo.c")
#define MODULE MODULE_FOO
#endif

有没有办法完成这样的事情?主要动机是避免将 #define MODULE 放在每个文件的顶部,而是在一个定义映射的位置并只包含相同的 .h 文件。

【问题讨论】:

  • "有什么办法可以完成这样的事情吗?" - 你试过这样做吗?成功了吗?
  • 贴出代码的结果是什么?
  • @ForceBru 不,该代码不起作用有几个原因,但由于您是人类而不是 C 编译器,您应该能够理解它的含义。大概这就是reza问这个问题的原因。
  • @reza 注意__FILE__ 将给出.h 文件的名称。对于 GCC,您可以使用 __BASE_FILE__ 在命令行上获取 .c 文件的名称,但这不能移植到不同的编译器。无论哪种方式,as melpomene says,预处理器都无法根据该字符串做出决定。

标签: c macros preprocessor


【解决方案1】:

不,你不能这样做。 #if 只能做整数表达式。它对字符串或如何比较它们一无所知。

【讨论】:

    【解决方案2】:

    你想要的是不可能使用标准 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)那个目的。

    请记住,编译器(特别是 GCCClang)是一个命令行程序,您应该从其他东西(如 makeninja 或许多其他构建自动化工具)驱动它。

    (即使在微软系统上,编译器仍然是一个命令行的东西,但这个事实经常被忽略)

    顺便说一句,我不喜欢很多IDEs,因为他们隐藏构建过程,你需要掌握它。因此,您需要对其进行配置(例如,通过编写您的 Makefile 或其他内容)并理解和调整它。

    主要动机是避免在每个文件的顶部放置#define MODULE,而是在一个定义映射的位置

    定义此类映射的单个位置可能应该是您的构建基础架构(例如,如果使用 make,则为您的 Makefile);您将调整它以使用适当的 -DMODULE=name 标志调用 gccclang(或大多数其他 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)。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 2011-12-18
    • 2010-09-23
    • 1970-01-01
    • 2011-02-19
    • 2010-11-15
    相关资源
    最近更新 更多