【问题标题】:Trouble with #ifdef across multiple files跨多个文件的#ifdef 问题
【发布时间】:2013-12-16 03:01:25
【问题描述】:

util.h 包含以下代码:

#ifdef DEBUG
#define LOGGER() MACRO_WRAP(printf("Entering %s\n", __func__))
#else
#define LOGGER() MACRO_WRAP()
#endif

foo.c 包含此代码:

void foo_start(foo *m)
{
    LOGGER();

    do_action(m, START);
}

然后foo_unit_tests.c 包含对foo_start() 的调用。我希望能够在相关文件的顶部#define DEBUG - 即我希望它为单元测试打开,但不是主要代码。

我无法让它工作。将#define DEBUG 放在foo_unit_tests.c 的顶部不会产生所需的行为。我可以让它工作的唯一方法是将#define DEBUG 放在util.hfoo.c 的顶部,这两个都比我想要的要混乱得多。

我在这里缺少什么?我认为.c 文件中定义的宏将在它包含的所有.h 文件中可见。

【问题讨论】:

  • 不是.h 文件包含.c 文件。这是相反的方式。预处理器会进行 textual 替换。它不是编译器。它不是链接器。想想这些事实,你就会明白为什么会出现错误。
  • 好的。为什么投反对票和势均力敌?我提交了相关的短代码 sn-ps 并展示了我解决问题的尝试,但我不确定这有什么离题?
  • 不是反对者之一,但反对者不会是关于问题的题外话。我确实看到你在解决这个问题方面做出了努力,所以我也不太同意近距离投票。

标签: c logging macros c-preprocessor conditional-compilation


【解决方案1】:

您必须在需要定义该宏的所有文件的开头添加#define,或者通过包含包含该宏的.h 文件。

如果您想要一种更简洁的方法,那么最好使用编译器标志来设置环境变量。

例如

icpc -DDEBUG=whatever source.c ...

或者更好的是,您可以通过 makefile 中的环境变量启用此编译器标志。

【讨论】:

    【解决方案2】:

    foo_unit_tests.c 很可能不包含 foo.c,因此编译 foo_unit_tests.c 时从未看到那里的#define

    【讨论】:

      【解决方案3】:

      在某处定义您的普通记录器..在单元测试中..

      #undef LOGGER()
      
      #define LOGGER(x) fprintf(stdout, x)
      

      或者你也可以这样做:

      #ifdef UNITTEST
          #define LOGGER ...
      #else
          #define LOGGER ...
      #endif
      

      并且在构建测试时从构建环境中传入 UNITTEST 宏

      【讨论】:

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