可能重复:
内联函数与预处理器宏
我想知道内联函数和宏函数的区别。
1)内联函数和宏函数一样吗?
2)我知道两者都没有被调用,但它们在编译阶段被其代码替换。不是?
3)如果有区别,你能指定吗?
内联用函数的主体替换对函数的调用,但是,内联只是对编译器的一个可以被忽略的请求(您仍然可以将一些标志传递给编译器以强制内联或使用带有 gcc 的always_inline属性)。
另一方面,宏在编译之前由预处理器扩展,所以它就像文本替换一样,宏也不是类型检查,内联函数是。维基上有一个比较。
为了完整起见,您仍然可以使用宏具有某种类型的安全性,__typeof__
例如使用 gcc,以下代码生成几乎相同的代码,并且如果与错误的类型一起使用都会导致警告:
#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++);
这可能不是你想要的。
宏是由预处理器(在实际编译之前)替换的声明,它们根本不是函数。在实际编译阶段开始之前,宏早已不复存在,剩下的就是它们的扩展(包括扩展为空)。
事实上,内联函数是符合语言的函数,具有范围规则、变量声明、逻辑构造(循环等)等等。内联函数不像宏那样在预编译步骤中扩展。它们像常规代码一样被编译,但随后可以注入(因为没有更好的术语)到编译后的代码中并根据需要进行优化。
否inline
与macro
定义不同,因为宏是预处理的,但内联只是指示编译器将函数的整个主体放在调用它的位置。
将 inline 关键字放在任何函数定义之前只是指示或请求,编译器可以自由选择是使该函数内联还是保持正常
宏替换:(preprocessing phase
即编译前)
test.c
--在linux中输入文件结果文件test.i
内联替换:compilation phase