【问题标题】:Undefine macro defined twice取消定义两次定义的宏
【发布时间】:2015-08-05 13:15:02
【问题描述】:

我想使用在不同头文件中定义的同名和不同实现的宏。 我有两个头文件h1.hh2.h。在我定义的第一个头文件中:

#define PRINT  printf(" hi , macro 1\n"); 

在第二个头文件中

#define PRINT  printf(" hi , macro 2\n");

main() 中,当我尝试使用 PRINT 时,它的打印取决于包含的顺序。 我发现了一些类似的问题,他们使用了一个包装器,通过包含第一个头文件然后定义一个内联方法:

inline void print1() {
      PRINT();
}

然后取消定义 PRINT 并包括第二个头文件。在main() 中,当我调用 print1() 和 PRINT 时,我得到了它们的输出。 我缺少的一点是,在我们从第一个头文件中取消定义 PRINT 之后,我们仍然能够拥有它 - 换句话说,当我们在内联函数中调用它时会发生什么?编译器是否复制了 PRINT 的值并将其分配给函数并以某种方式保存函数?

【问题讨论】:

  • 惊喜,您正在使用预处理器 MACRO... :-)

标签: c macros


【解决方案1】:

如果我理解正确,就会发生这样的事情:

#include "h1.h" // defines PRINT: printf(" hi , macro 1\n"); 

inline void print1(){
    PRINT();
}

#undef PRINT

#include "h2.h" // defines PRINT: printf(" hi , macro 2\n");

不过没有什么奇怪的事情发生。预处理器在未定义之前替换内联函数内部的PRINT。所以在生成的代码中(当你使用 GCC 的 -E 标志编译时可以看到),它变成了这样:

// contents of h1.h...

inline void print1(){
    printf(" hi , macro 1\n");
}

// contents of h2.h...

#defined 宏仅在预处理期间保留,并在预处理器进行时被替换。与普通编程中的变量类似,如果您重新分配它,预处理器只会将新值用于以下事件。

【讨论】:

    【解决方案2】:

    之所以有效,是因为在编译期间,预处理器到达print1 中的PRINT() 调用,评估宏,并将其替换为当前值。然后,如果我理解正确,稍后(在下一行中)您重新定义或取消定义 PRINT(无论是通过包含另一个标题),然后对它的任何进一步引用都会使预处理器再次用其当前值替换它(即现在不同),因此您会得到两种不同的行为,称为“相同”宏。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-06
      • 2015-11-04
      相关资源
      最近更新 更多