以下两个定义之间的区别是什么:
#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; } \
答案 0 :(得分:2)
单词“inline
”向某些编译器发出信号,如果可能,应该内联函数,即函数体的代码应该“复制粘贴”到调用站点,而不是作为一个站点生成单独的功能。
这可以节省时间,因为如果正在完成的工作小于进行呼叫本身的工作,那么删除它就是一个净胜利。它还可以通过膨胀代码和终止缓存来减慢速度。
答案 1 :(得分:2)
根据我的口味,所有的答案,即使是被接受的答案,都会导致inline
的主要方面出错,特别是对于在宏中使用的含义,我会尝试另外一个。
inline
关键字确定函数定义(非声明)是否会导致在当前编译单元中生成函数。基本上有3种情况:
inline
定义一个函数
可以生成,如果是,则可以插入或不插入外部符号
对象。static
定义一个函数
可能生成(通常如果使用它),但名称永远不会是
外部符号。对于第一个,如果两个编译单元定义相同的函数,则在一个可执行文件中将两个目标文件链接在一起时会出错。
对于后者,如果两个编译单元定义相同的函数,则两个目标文件都将包含在链接时不会合并的函数的副本。
对于问题中提出的宏,这会产生重要的功能差异。第一个inline
可以在任何地方扩展,尤其是在头文件中,而不会引起冲突。第二个只能在.c文件中使用,此外,如果它们最终应该在同一个可执行文件中,那么没有两个这样的.c应该这样做。
编辑: w.r.t对Charles的评论。 inline
函数也可能是外部符号。其规则有点复杂,见下文C99的相应第6.7.4段。基本上,如果您有多个将链接在一起的翻译单元,则有三种情况可行。
extern inline
的{{1}}。inline
并在没有重新声明的情况下重新声明
只有一个.c文件中的extern
。这实际上类似于C ++中模板函数的实例化。inline
并重新声明它
只有一个.c文件中的inline
。在4.3版之前,gcc对这种inline
函数的实例化有一个不同的模型,它与这个标准函数不兼容。 See also this page for a good read on this subject.
任何具有内部联系的功能都可以 是一个内联函数。对于一个功能 与外部联系,以下 限制适用:如果是函数 用内联函数声明 说明者,那么它也应该是 在同一翻译单元中定义。 如果所有文件范围声明 用于翻译单元中的功能 包括内联函数说明符 没有extern,那么定义在 该翻译单位是内联的 定义。内联定义可以 没有提供外部定义 功能,并不禁止 外部定义在另一个 翻译单位。内联定义 提供外部的替代 定义,翻译人员可以使用 实现对该函数的任何调用 在同一翻译单位。它是 未指定是否致电 函数使用内联定义或 外部定义。
答案 2 :(得分:0)
不同之处在于,在第一种情况下,没有发生功能调用。该函数是'inlined',这意味着调用被替换为方法体。它有助于优化执行,因为在调用之前不必保存上下文并在之后恢复。
答案 3 :(得分:0)
这是一个有效的关键字,主要是当编译器不能很好地确定它是否适合内联时。今天的现代编译器在确定这一点时通常要好得多,必要时使用链接时代码生成(整个程序分析)。
答案 4 :(得分:0)
“inline”关键字用于向编译器指示您希望它执行函数的内联扩展,或者换句话说,扩展函数来代替调用。
要点几点
答案 5 :(得分:0)
我在unwind's answer的评论中指出,您想了解以下内容:
如果某项功能无法内联,并且已被标记,那么如果您将-Winline
传递给GCC,则会收到警告。