内联函数与宏函数

可能重复:
内联函数与预处理器宏

我想知道内联函数和宏函数之间的区别。

1)内联函数是否与宏函数相同?

2)我知道两者都没有被调用,但它们在编译阶段被代码替换。 不是?

3)如果有差异,你能指定吗?

内联使用函数体替换对函数的调用,但是,内联只是对编译器的一个可以忽略的请求 (您仍然可以将一些标志传递给编译器以强制内联或使用带有gcc的always_inline属性)。

另一方面,宏在编译之前由预处理器扩展,因此它就像文本替换一样,宏也不是类型检查,内联函数是。 在wiki中有一个比较。

为了完整起见,您仍然可以使用__typeof__某种类型的安全性,例如,使用gcc的__typeof__ ,以下代码生成几乎相同的代码,如果使用错误类型,则会导致警告:

 #define max(a,b) \ ({ __typeof__ (a) _a = (a); \ __typeof__ (b) _b = (b); \ _a > _b ? _a : _b; }) __attribute__((always_inline)) int max(int a, int b) { return (a > b ? a : b); } 

注意:有时无格式的宏只是需要的东西,例如,看看uthash如何使用宏来使任何C结构可以在不使用强制转换的情况下进行清理 。

1)不。

2)C中的宏只是在编译器处理源代码之前扩展的文本。 inline关键字用作编译器的提示,函数可以内联放置而无需设置调用堆栈。

因此,例如,假设您有以下两段代码(首先是宏,然后是内联函数):

 #define MAX(x,y) (x > y ? x : y) 

 inline int max(int x, int y) { return x > y ? x : y; } 

当预处理器在您的代码中找到以下调用时:

 int highest = MAX (var_1, var_2); 

它取代了它

 int highest = (var_1 > var_2 ? var_1 : var_2); 

以上是编译器在编译过程中最终获得的内容,因此MAX(x,y)定义的片段是MAX(var_1,var_2)的替代 。 当编译器找到函数调用时

 int highest = max (var_1, var_2); 

然后调用函数“max”。 你必须假设它被称为正常方式,因为编译器可以自由地忽略你的“内联”提示并且对该函数的调用通过正常的调用栈而不是简单地将函数的代码放在它所在的位置。遇到。

最后一点请注意宏:因为它是所有文本替换而不是代码替换,如果你这样做:

 int highest = MAX (v1++, v2++); 

预处理器将扩展到:

 int highest = (v1++ > v2++ ? v1++ : v2++); 

这可能不是你想要的。

宏是由预处理器替换的声明(在实际编译之前)根本不是函数。 在实际的编译阶段开始之前,宏已经很久了,剩下的就是它们的扩展(包括扩展为空)。

事实上,内联函数是符合语言的函数 ,包括范围规则,变量声明,逻辑结构(循环等)等。 内联函数不像宏那样在预编译步骤之外扩展。 它们被编译为常规代码,但是可以将其注入(缺少更好的术语)到编译代码中并根据需要进行优化。

inlinemacro定义不同,因为宏是预处理的,但内联只是指示编译器将函数的整个主体放在调用它的位置。

在任何函数定义之前放置内联关键字只是指示或请求,编译器可以自由选择是否将该函数内联或保持正常

宏替换: preprocessing phase (即编译前)

– 在linux test.i输入文件test.c结果文件

内联替换: compilation phase