请不要在这里重定向到那里的答案 - 我已经阅读了它们,以及其他所有在互联网上的答案,包括标准,但我仍然感到困惑(大多数情况下,我认为是因为技术词汇的重叠,英语单词和语言关键词)。
让我直截了当地说,在C99中,用于功能:
static
:不要产生任何外部符号
extern
(隐式):如果此翻译单元中没有定义,编译器会生成在链接期间解析的引用
现在使用inline
。据我所知,由于编译器可能选择内联或不内联,因此问题很复杂。
我可以通过两种不同的方式看到这一点:
static inline
似乎是#1的答案:
static inline
函数,那就去吧。 static
存储说明符与非内联函数的使用一致,因为不会产生外部符号。由于是这种情况,如果编译器决定在翻译单元中的每个调用站点内联static inline
函数,则无需生成独立的目标代码。static inline
函数,则它可以在翻译单元内生成独立的目标代码,并且不会为其导出外部符号。据我所知,extern inline
/ inline
是#2的答案:
inline
(没有extern
或static
)的行为与#2相同。如果编译器实际上没有内联它们,那么在链接时需要链接外部实现。extern inline
。 我认为这是最重要的
令人困惑,因为正常函数的extern
关键字表现在
几乎完全相反的方式 这是对的吗?
相关链接,但仍留下模糊的角落:
Is “inline” without “static” or “extern” ever useful in C99?
答案 0 :(得分:2)
您对此的全面理解是正确的。
实际导出要链接的符号的翻译单元必须声明为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方式)。