繁体   English   中英

C99中的inline,static,extern

[英]inline, static, extern in C99

请不要在这里重定向到那里的答案 - 我已经阅读了它们,以及互联网上的其他答案,包括标准,但我仍然感到困惑(大多数情况下,我认为是因为技术词汇,英语单词和语言的重叠关键字)。


让我在C99中直截了当地了解函数

static :不产生任何外部符号

extern (隐式):如果此转换单元中没有定义,则编译器会生成在链接期间解析的引用


现在有了inline 据我所知,由于编译器可能选择内联或不内联,因此问题很复杂。

  • 如果编译器决定内联,显然实现必须在编译时可见
  • 如果编译器决定不内联,哪个函数被链接,以及该代码在哪个翻译单元中存在?

我可以通过两种不同的方式看到这个答案:

  1. 如果编译器决定不在某个调用站点内联函数,则在同一个转换单元内生成非内联对象代码。 不会为此导出外部符号。
  2. 如果编译器决定不在某个调用站点内联函数,那么这表现为普通函数,并且必须有一个转换单元导出外部符号并包含实现该函数的目标代码。

static inline似乎是#1的答案:

  • 如果编译器决定内联static inline函数,那么就去做吧。 static存储说明符与非内联函数的使用一致,因为不会产生外部符号。 由于这种情况,如果编译器决定在转换单元内的每个调用站点内联static inline函数,则不需要生成独立的目标代码。
  • 如果编译器决定不在某个调用站点内联static inline函数,那么它可以在转换单元内生成独立的目标代码,并且不会为其导出外部符号。

据我所知, extern inline / inline是#2的答案:

  • 所有inline (没有externstatic )的行为类似于#2。 如果编译器实际上没有内联它们,那么在链接时需要链接外部实现。
  • 实际导出要链接的符号的翻译单元必须声明为extern inline 我认为这是最令人困惑的,因为正常函数的extern关键字几乎完全相反

它是否正确?


相关链接,但仍然留下模糊的角落:

没有“静态”或“外部”的“内联”在C99中是否有用?

外部内联

新C:内联函数

您对此的总体理解是正确的。

实际导出要链接的符号的翻译单元必须声明为extern inline。 我认为这是最令人困惑的,因为正常函数的extern关键字几乎完全相反

是的,这是该语言的一个不幸的部分,但你有权利。


作为一小部分琐事(希望不会让你感到困惑),GNU gcc 用于处理“内联”和“外部内联”与C99 / C11标准对待它们的方式完全相反。 在这种情况下,GNU会将“内联”解释为“使用此定义以内联AND生成此函数的外部,外部可见定义”,并将“extern inline”视为“仅使用此定义进行内联” ;如果没有发生内联,则发出对函数的extern引用(必须在别处定义)“。

无论出于何种原因,C99标准选择交换“内联”和“外部内联”的含义,现在我们坚持使用它。

注意:快速测试表明,如果不通过-std = c99 / c11或-fno-gnu89-inline,GNU gcc v4.9.2将默认采用“GNU”方式(-fgnu89-inline)。 在那时和GNU gcc v5.2.1之间的某个时间它发生了变化,因为v5.2.1将默认为-fno-gnu89-inline(即标准的C99 / C11方式)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM