这里的内联是什么?

时间:2010-11-24 10:56:42

标签: c syntax

以下两个定义之间的区别是什么:

#define DEFINE_BIT_MASK_ENUM_AND_OR(Type) \
inline Type EnumBitMaskOr(Type lhs, Type rhs) { return lhs | rhs; } \

#define DEFINE_BIT_MASK_ENUM_AND_OR(Type) \
Type EnumBitMaskOr(Type lhs, Type rhs) { return lhs | rhs; } \

6 个答案:

答案 0 :(得分:2)

单词“inline”向某些编译器发出信号,如果可能,应该内联函数,即函数体的代码应该“复制粘贴”到调用站点,而不是作为一个站点生成单独的功能。

这可以节省时间,因为如果正在完成的工作小于进行呼叫本身的工作,那么删除它就是一个净胜利。它还可以通过膨胀代码和终止缓存来减慢速度。

答案 1 :(得分:2)

根据我的口味,所有的答案,即使是被接受的答案,都会导致inline的主要方面出错,特别是对于在宏中使用的含义,我会尝试另外一个。

inline关键字确定函数定义(非声明)是否会导致在当前编译单元中生成函数。基本上有3种情况:

  • 如果你只是提出一个“简单”的定义 必须生成函数 该函数的外部符号 插入。
  • 对于inline定义一个函数 可以生成,如果是,则可以插入或不插入外部符号 对象。
  • static定义一个函数 可能生成(通常如果使用它),但名称永远不会是 外部符号。

对于第一个,如果两个编译单元定义相同的函数,则在一个可执行文件中将两个目标文件链接在一起时会出错。

对于后者,如果两个编译单元定义相同的函数,则两个目标文件都将包含在链接时不会合并的函数的副本。

对于问题中提出的宏,这会产生重要的功能差异。第一个inline可以在任何地方扩展,尤其是在头文件中,而不会引起冲突。第二个只能在.c文件中使用,此外,如果它们最终应该在同一个可执行文件中,那么没有两个这样的.c应该这样做。


编辑: w.r.t对Charles的评论。 inline函数也可能是外部符号。其规则有点复杂,见下文C99的相应第6.7.4段。基本上,如果您有多个将链接在一起的翻译单元,则有三种情况可行。

  1. 声明并定义该函数 {。1}在.h文件中,再次声明 只有一个.c文件中没有extern inline的{​​{1}}。
  2. 声明并定义该函数 在.h文件中inline并在没有重新声明的情况下重新声明 只有一个.c文件中的extern。这实际上类似于C ++中模板函数的实例化。
  3. 声明并定义该函数     在.h文件中inline并重新声明它     只有一个.c文件中的inline
  4. 在4.3版之前,gcc对这种inline函数的实例化有一个不同的模型,它与这个标准函数不兼容。 See also this page for a good read on this subject.

      

    任何具有内部联系的功能都可以   是一个内联函数。对于一个功能   与外部联系,以下   限制适用:如果是函数   用内联函数声明   说明者,那么它也应该是   在同一翻译单元中定义。   如果所有文件范围声明   用于翻译单元中的功能   包括内联函数说明符   没有extern,那么定义在   该翻译单位是内联的   定义。内联定义可以   没有提供外部定义   功能,并不禁止   外部定义在另一个   翻译单位。内联定义   提供外部的替代   定义,翻译人员可以使用   实现对该函数的任何调用   在同一翻译单位。它是   未指定是否致电   函数使用内联定义或   外部定义。

答案 2 :(得分:0)

不同之处在于,在第一种情况下,没有发生功能调用。该函数是'inlined',这意味着调用被替换为方法体。它有助于优化执行,因为在调用之前不必保存上下文并在之后恢复。

答案 3 :(得分:0)

这是一个有效的关键字,主要是当编译器不能很好地确定它是否适合内联时。今天的现代编译器在确定这一点时通常要好得多,必要时使用链接时代码生成(整个程序分析)。

答案 4 :(得分:0)

“inline”关键字用于向编译器指示您希望它执行函数的内联扩展,或者换句话说,扩展函数来代替调用。

要点几点

  1. 通常这样做的原因是为了节省调用另一个函数的开销
  2. “inline”关键字只是对编译器的请求,编译器可以决定是否遵守它
  3. 内联可能会产生意想不到的后果,因此应谨慎使用
  4. 编译器今天通常会更好地决定哪些函数应该为您内联,如果为编译器提供了适当的参数,它会自动执行此操作

答案 5 :(得分:0)

我在unwind's answer的评论中指出,您想了解以下内容:

如果某项功能无法内联,并且已被标记,那么如果您将-Winline传递给GCC,则会收到警告。