代码之家  ›  专栏  ›  技术社区  ›  reza

是否可以使用预处理器\uu file\uuuu在C中生成\define?

  •  0
  • reza  · 技术社区  · 7 年前

    为了提高一些代码的美观性,我想有一个。h文件包含一些代码,这些代码设置了#定义,定义基于哪个文件。h文件包含在中。例如

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

    有什么方法可以完成这样的事情吗?主要动机是避免在每个文件的顶部放置#define模块,而是在一个位置定义映射,并只包含相同的映射。h文件。

    2 回复  |  直到 7 年前
        1
  •  4
  •   melpomene    7 年前

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

        2
  •  1
  •   Basile Starynkevitch    7 年前

    你想要的是 不可能 使用标准的C预处理器。通过阅读C标准进行检查,例如 n1570 ,或一些 C reference ,或 wikipage on the C preprocessor ,或 GNU cpp manual

    但请考虑另一种实现相同功能的方法:配置 适当地 你的 build automation

    例如,如果使用 make ,然后编辑 Makefile 适当地。如何做到这一点是一个非常不同的问题。

    你可以有一个规则 制作 通过特定 -DMODULE= 名称 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 $@
    

    要有创造力 。构建机制是源代码的一部分。调整它来做你想做的事。不要期望标准预处理器能够满足您的所有需求。了解如何 invoke GCC (或您最喜欢的编译器) command line 在里面 some cases ,甚至值得 生成 一些C文件(可能是一些头文件),您可以使用 另一个 预处理器(如 GPP 或m4)。

    请记住,编译器(尤其是 GCC Clang )是一个命令行程序,您应该从其他程序(如 制作 ,则, ninja 或许多其他构建自动化工具)。

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

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

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

    定义这种映射的单一位置可能应该是您的构建基础架构(例如 生成文件 如果使用 制作 );您将调整它以调用 通用条款 clang (或大多数其他C编译器)具有适当的 -D模块= 名称 旗帜(顺便说一句,您还需要 习俗 源文件的基本名称是C标识符,因此没有任何 a-1.c 文件-自 a-1 不是标识符,而是 bcde.c 一个)。

    如果使用GNU 制作 ,读取其 documentation ,然后运行 make -p 了解与您的案例相关的规则(包括内置规则和自定义规则)。然后考虑一条类似的规则:

    %.o: %.c $(YOURHEADERS)
         $(COMPILE.c) -DMODULE=$(patsubst %.c,MODULE_%,$^) -c $< -o $@
    

    但是 调整规则 满足您的需求。(你可能需要一些 $(shell 。。。 ) 如果您的文件名是小写的,而您想要大写的,那么在它里面 MODULE )。

    顺便说一句,您还可以生成 生成文件 (或者吃一些 已生成 C文件 #include 适当地)。

    推荐文章