宏保证没有头脑?

时间:2016-12-20 16:27:24

标签: c++ c

作为一名程序员,我已经被教导要将关键字内联更喜欢小功能的宏定义。我知道由于宏定义不进行类型检查,内联已知更安全,但是我被告知内联只是请求编译器实际替换代码,并且编译器不必接受请求,所以我想知道宏请求还是保证没有超时?

3 个答案:

答案 0 :(得分:8)

宏是在编译步骤之前执行的文本替换 - 它们不能具有"运行时开销"以函数调用的方式。尽管如此,这并不是使用宏而不是函数的好理由,因为即使没有启用优化的inline关键字,编译器也会自动内联函数。此外,使用链接时间优化-flto将允许在TU之间进行内联。

答案 1 :(得分:2)

宏是编译时的东西。它们从未在编译代码中显示为宏。如果您定义类似

的内容
#define MyVar 5

你在代码中做了:

double y = MyVar*MyVar;

这就像:

double y = 5*5;

在编译时,MyVar宏被替换您定义的值。在运行时绝对没有开销。

答案 2 :(得分:1)

宏是预处理器功能。

预处理程序以纯文本方式修改程序,如果单独运行预处理程序,实际上可以看到它的结果。

使用gcc,您可以使用gcc -Ecpp执行此操作。 我在调试宏时经常这样做。

示例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