内联函数与宏函数

MOH*_*MED 16 c macros inline

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

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

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

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

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

iab*_*der 24

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

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

为了完整起见,您仍然可以使用宏来保持某种类型的安全性,__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);
}
Run Code Online (Sandbox Code Playgroud)

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


Lel*_*ran 20

1)不.

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

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

#define MAX(x,y)     (x > y ? x : y)
Run Code Online (Sandbox Code Playgroud)

inline int max(int x, int y) { return x > y ? x : y; }
Run Code Online (Sandbox Code Playgroud)

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

int highest = MAX (var_1, var_2);
Run Code Online (Sandbox Code Playgroud)

它取代了它

int highest = (var_1 > var_2 ? var_1 : var_2);
Run Code Online (Sandbox Code Playgroud)

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

int highest = max (var_1, var_2);
Run Code Online (Sandbox Code Playgroud)

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

最后一点请注意宏:因为它是所有文本替换而不是代码替换,如果您执行以下操作:

int highest = MAX (v1++, v2++);
Run Code Online (Sandbox Code Playgroud)

预处理器将扩展到:

int highest = (v1++ > v2++ ? v1++ : v2++);
Run Code Online (Sandbox Code Playgroud)

这可能不是你想要的.


Who*_*aig 6

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

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