C语言中的存储类说明符有哪些?各自的含义如何?

如题所述

inline int foo(int a, int b) { return a + b; } int main(int argc, char *argv[]){return(1,2);

*ANSI C, ISO/IEC C89/C90:标准中没有inline关键字.

*GNU C89/C90:

1、static inline:函数名标识符的作用域为当前编译单元(translation unit),允许其他编译单元中有重名定义. 这里的inline建议编译器,函数在被调用时可以直接展开函数体,但是否展开取决于编译器.(譬如,如果优化级别为-O0,则必须按函数地址调用,此时编译器会忽略inline请求,将函数编译为普通函数;或者,出现了递归调用,编译器也无法内联这个函数)

2、inline:在当前编译单元内,和static inline语义相同,都是建议编译器在当前编译单元内展开函数体(是否展开取决于编译器). 但同时编译器会对该函数生成一份普通函数的代码,在其他编译单元内可以调用,与普通的extern函数调用无异.

3、extern inline:相当诡异. 这样的函数定义只为内联而提供. 如果强行用普通函数调用方式调用该函数(譬如,优化级别为-O0,或者按函数指针调用),则链接器会认为存在另一个同名的普通函数. 如果没有这个同名普通函数的定义,则链接器会报告找不到符号.

*ISO/IEC C99/C11:

1、static inline:和GNU C89/C90中的语义完全相同.

2、inline:很类似GNU C89/C90中的extern inline. 标准文档中的解释相当晦涩:允许(但不要求)编译器在当前编译单元内展开函数体(原文的描述是“相比正常的函数调用机制,让内联函数调用尽可能快”,而文档下面的脚注中提到,可能的选择是“内联替换”,见ISO/IEC 9899:1999或ISO/IEC 9899:2011),是否内联由编译器设计者自行决定,同时也允许外部存在同名的普通函数定义. 经测试最新版本的Clang和GCC在标准-std=c99和-std=c11下会在可以内联的情况下(例如优化级别为-O2)采用内联版本.

3、但标准文档中同时也规定了,若在函数声明中加入extern,则相应的内联函数定义成为所谓的外部定义,行为和GNU C89/C90的inline相同:在当前编译单元中建议编译器展开函数体,同时生成一份普通函数的代码,在其他编译单元中也可调用.

4、extern inline:标准文档中未见extern inline的定义.

*GNU C99/C11:采用与ISO/IEC C99/C11相同的语义.

最新版本的Clang和GCC默认均采用GNU C11标准,因此会出现不优化代码时找不到内联函数符号的错误.

温馨提示:答案为网友推荐,仅供参考

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网