作为一名程序员,我已经被教导要将关键字内联更喜欢小功能的宏定义。我知道由于宏定义不进行类型检查,内联已知更安全,但是我被告知内联只是请求编译器实际替换代码,并且编译器不必接受请求,所以我想知道宏请求还是保证没有超时?
答案 0 :(得分:8)
宏是在编译步骤之前执行的文本替换 - 它们不能具有"运行时开销"以函数调用的方式。尽管如此,这并不是使用宏而不是函数的好理由,因为即使没有启用优化的inline
关键字,编译器也会自动内联函数。此外,使用链接时间优化-flto
将允许在TU之间进行内联。
答案 1 :(得分:2)
宏是编译时的东西。它们从未在编译代码中显示为宏。如果您定义类似
的内容#define MyVar 5
你在代码中做了:
double y = MyVar*MyVar;
这就像:
double y = 5*5;
在编译时,MyVar
宏被替换您定义的值。在运行时绝对没有开销。
答案 2 :(得分:1)
宏是预处理器功能。
预处理程序以纯文本方式修改程序,如果单独运行预处理程序,实际上可以看到它的结果。
使用gcc,您可以使用gcc -E
或cpp
执行此操作。
我在调试宏时经常这样做。
示例main.c:
#include <stdio.h>
#define MC_repeat(X) \
for(int _i=0;_i<(X);_i++)
#define rt return
#define MC_xputs(X) if(0>puts(X)) rt -1;
int main()
{
MC_repeat(5)
MC_xputs("hello world");
rt 0;
}
gcc -E main.c | tail
的输出:
# 2 "main.c" 2
# 11 "main.c"
# 11 "main.c"
int main()
{
for(int _i=0;_i<(5);_i++)
if(0>puts("hello world")) return -1;;
return 0;
}
编译这样的源时,它实际上就像先运行preprocesser然后将结果传递给编译器一样。
gcc实际上并没有这样做(所以你得到更好的错误信息),但你可以强制它:
#actually pipes preprocessor output to the compiler proper
gcc -E main.c | gcc -x cpp-output