我想使用在具有相同名称和不同实现的不同头文件中定义的宏。
我有两个头文件h1.h
和h2.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的值并将其分配给函数并以某种方式保存函数?
答案 0 :(得分:3)
如果我理解正确,就会发生这样的事情:
#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...
#define
d宏仅在预处理期间保留,并在预处理器进行时被替换。与正常编程中的变量类似,如果重新分配,预处理器将仅使用新值进行后续出现。
答案 1 :(得分:1)
它的工作原理是因为在编译期间预处理器到达PRINT()
中的print1
调用,评估宏,并用其当前值替换它。然后,如果我理解正确,稍后(在下一行中)你重新定义或取消定义PRINT(通过包含另一个标题),那么对它的任何进一步引用将使预处理器再次用它的当前值替换它(这是现在不同了,因此你得到2个不同的行为,称为"相同"宏。