“静态”和“静态内联”function有什么区别?

国际海事组织(IMO)只是将function做为翻译单位的范围,

“静态”和“静态内联”function有什么区别?

UPDATE

为什么要inline放在头文件,而不是.c文件?

inline指示编译器尝试将函数内容embedded到调用代码中,而不是执行实际调用。

对于经常被调用的小函数,可能会造成巨大的性能差异。

然而,这只是一个“提示”,编译器可能会忽略它,大多数编译器会尝试“内联”,即使在关键字未被使用的情况下,作为优化的一部分,在可能的情况下也是如此。

例如:

 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*/}; 

这个紧密的循环将在每次迭代中执行函数调用,而函数内容实际上比编译器执行调用所需的代码要less得多。 inline将主要指示编译器将上面的代码转换为等同于:

  int i; .... for (i=0; i<999999; i = i+1) { /* do something here */}; 

跳过实际的函数调用并返回

显然这是一个例子来显示这一点,而不是一个真正的代码。

static是指范围。 在C中,这意味着函数/variables只能在同一个翻译单元中使用。

默认情况下,内联定义仅在当前的翻译单元中有效。

如果存储类是extern ,则标识符具有外部链接,并且内联定义也提供外部定义。

如果存储类是static ,则标识符具有内部链接,并且内联定义在其他翻译单元中是不可见的。

如果未指定存储类别,则内联定义仅在当前的翻译单元中可见,但标识符仍具有外部链接,必须在不同的翻译单元中提供外部定义。 如果函数在当前的翻译单元中被调用,编译器可以自由使用内联或外部定义。

由于编译器可以内联(而不内联)任何定义在当前翻译单元中可见的函数(并且,由于链接时优化,甚至在不同的翻译单元中,尽pipeC标准没有真正考虑),大多数实际的目的, staticstatic inline函数定义没有区别。

inline说明符(如register存储类)只是一个编译器提示,编译器可以完全忽略它。 符合标准的非优化编译器只需要遵守它们的副作用,优化编译器就可以在有或没有明确提示的情况下进行这些优化。

inlineregister并不是无用的,因为它们指示编译器在程序员编写代码时会抛出错误,使优化变得不可能:外部inline定义不能引用具有内部链接的标识符(因为这些标识符在不同的翻译单元),或者定义具有静态存储持续时间的可修改局部variables(因为它们不会共享翻译单元的状态),并且不能获取register限定variables的地址。

就我个人而言,我使用约定来标记头中的static函数定义也是inline ,因为在头文件中放置函数定义的主要原因是为了让它们可以被映射。

一般来说,除了标题中的extern声明之外,我只使用static inline函数和static const对象定义。

我从来没有写过一个不同于static的存储类的inline函数。

根据我对GCC的经验,我知道staticstatic inline不同之处在于编译器如何发出关于未使用函数的警告。 更确切地说,当你声明static函数并且它不被当前的翻译单元使用时,编译器会产生关于未使用的函数的警告,但是你可以通过将它改变为static inline来禁止该警告。

因此,我倾向于认为, static应该用在翻译单位,并从额外的检查编译器中获益,find未使用的function。 在头文件中应该使用static inline ,以提供可以static inlinefunction(由于没有外部链接)而不发出警告。

不幸的是,我找不到这个逻辑的证据。 即使从GCC文档,我也无法得出结论, inline禁止未使用的function警告。 我会很感激,如果有人会分享链接的描述。

一个不同于语言级别但stream行的实现级别的区别:特定版本的gcc将默认从输出中移除未引用的static inline函数,但即使未引用也会保留纯static函数。 我不确定这个版本适用于哪个版本,但从实际的angular度来看,这意味着在标题中始终使用inline static函数是一个好主意。

在C中, static意味着你定义的函数或variables只能在这个文件中使用(即编译单元)

所以, static inline意味着只能在这个文件中使用的内联函数。

编辑:

编译单位应该是翻译单位