Answers:
inline
指示编译器尝试将函数内容嵌入到调用代码中,而不是执行实际的调用。
对于经常调用的小函数,可能会产生很大的性能差异。
但是,这只是一个“提示”,编译器可能会忽略它,并且即使在可能的情况下,作为优化的一部分,即使不使用该关键字,大多数编译器也会尝试“内联”。
例如:
static int Inc(int i) {return i+1};
.... // some code
int i;
.... // some more code
for (i=0; i<999999; i = Inc(i)) {/*do something here*/};
这个紧密的循环将在每次迭代时执行一个函数调用,并且函数内容实际上比编译器执行该调用所需的代码少得多。inline
本质上将指示编译器将上面的代码转换为以下代码:
int i;
....
for (i=0; i<999999; i = i+1) { /* do something here */};
跳过实际的函数调用并返回
显然,这是一个说明问题的示例,而不是真正的代码。
static
指范围。在C语言中,这意味着该函数/变量只能在同一翻译单元中使用。
static
(带或不带inline
)可以很好地放在标题中,看不出为什么没有。模板是用于C ++的,这个问题是关于C的
inline
是一种好的样式,imo
inline
并不指示编译器进行任何内联尝试。它仅允许程序员在不违反ODR的情况下将功能主体包含在多个转换单元中。这方面的一个副作用是,它是它使编译器,当它会内联函数,要真正做到这一点。
默认情况下,内联定义仅在当前翻译单元中有效。
如果存储类为extern
,则标识符具有外部链接,并且内联定义还提供了外部定义。
如果存储类为static
,则标识符具有内部链接,并且内联定义在其他翻译单元中不可见。
如果未指定存储类别,则内联定义仅在当前翻译单元中可见,但是标识符仍具有外部链接,并且必须在其他翻译单元中提供外部定义。如果在当前翻译单元中调用函数,则编译器可以自由使用内联或外部定义。
由于编译器可以自由地内联(或不内联)任何在当前翻译单元中可见其定义的函数(并且由于链接时的优化,即使在不同的翻译单元中也可以使用),尽管C标准并未真正考虑到那),对于大多数实际目的,static
和static inline
函数定义之间没有区别。
的inline
说明符(如register
存储类)只有一个编译器暗示,编译器可以自由地完全忽略它。符合标准的非优化编译器仅需遵守其副作用,优化编译器将在有或没有显式提示的情况下进行这些优化。
inline
而且register
并不是没有用的,因为它们指示程序员在编写使优化无法实现的代码时引发编译器错误:外部inline
定义不能引用具有内部链接的标识符(因为这些标识符在其他翻译单元中不可用)或定义具有静态存储持续时间的可修改局部变量(因为它们不会在翻译单元之间共享状态),并且您不能使用- register
限定变量的地址。
就我个人而言,我也使用约定static
在标头中标记函数定义inline
,因为将函数定义放在标头文件中的主要原因是使它们不可插入。
通常,除了使用static inline
函数和static const
对象定义外,我只使用extern
标头中的声明。
我从未用inline
存储类不同于编写过函数static
。
inline
好像实际上应用于内联的答案都是误导性的,并且可以说是错误的。没有现代的编译器使用它作为内联或要求它来启用函数内联的提示。
根据我在GCC中的经验,我知道这一点,static
并且static inline
在编译器发出有关未使用功能的警告的方式方面有所不同。更准确地说,当您声明static
函数且当前转换单元中未使用该函数时,编译器会生成有关未使用函数的警告,但可以通过将其更改为来禁止该警告static inline
。
因此,我倾向于认为static
应该在翻译单元中使用它,并受益于额外的检查编译器来查找未使用的函数。并且static inline
应在头文件中使用,以提供可以内联的功能(由于缺少外部链接)而不会发出警告。
不幸的是,我找不到这种逻辑的任何证据。即使从GCC文档中,我也无法得出结论,inline
可以禁止未使用的功能警告。如果有人会共享指向其描述的链接,我将不胜感激。
warning: unused function 'function' [clang-diagnostic-unused-function]
了static inline
以建设时功能clang-tidy
(V8.0.1),但是以另一种翻译单位使用。但这绝对是结合static
&inline
!的最佳解释和原因之一。
不是在语言级别而是在流行的实现级别上的一个区别:static inline
默认情况下,某些版本的gcc 将从输出中删除未引用的函数,但是static
即使未引用,它们也会保留纯函数。我不知道这适用于哪个版本,但是从实际情况来看这意味着它可能是一个好主意,始终使用inline
的static
标头的功能。
inline
定义使用呢?您是否还暗示不将其用于extern
功能?
attribute((used))
及其使用来允许asm引用未引用的static
函数和数据,从而找到gcc何时开始优化未使用的静态函数/对象。
static
是指范围。在C语言中,这意味着该函数/变量只能在同一翻译单元中使用。