五、inline关键词

        大家都知道它会快, 但我想说一点我之前不知道的: 如果希望inline有效果, 使用的地方就得与定义的地方在同一个文件, 得知道函数体. 我觉得原因是这样的: 如果不在一个文件, 那么调用它的函数就必然会是call了, call的话, 就不会省去任何函数的开销. 我们知道, c是单文件编译的(局限我的所知), 它看不到其它文件. 反过来, 如果函数体与调用在同一个文件中, 那么就可以把这个函数拷贝过去, 然后再来编译.

        因此如果是多文件都需要使用, 典型做法是在一个头文件中实现(是的, 与一般的头文件不包括实现的规则不同, 这是个例外), 然后声明为static(否则有重定义问题). 当然也是有代价的:

        编译得到的文件变大了些;函数没有地址, 没法用函数指针, debugger也用不了;当然你可能发现第2点说的不对, 如果用函数指针, 编译器也没有报错, 那是因为编译器看到用了函数指针, 放弃了优化. inline只是建议, 不一定真的优化.

        inline这个关键词,是从C99开始出现的。它要解决的问题很明确,对于那些短小精干频繁调用的函数,如果是inline的,编译的时候,函数调用位置会被替换成函数的代码块,省掉了函数调用的压栈出栈等操作,可以加快程序的执行速度,代价只是增加了一点点程序文件的体积。本文以gcc的inline行为为准。

        1, static inline

        这是最纯粹的inline用法,我们始终要记住,C语言的编译是按文件进行的,每个.c文件单独编译,最后链接在一起。既然是单独编译,要发挥inline的作用,定义为inline的函数,必然要与调用者在同一个文件中。static inline的语义,就是先static,此函数只在当前文件可见,然后inline,在调用处展开。

        另外,inline要出现在函数定义(definition)的地方,出现在申明(declaration)的地方没有意义!如果一个函数是static inline,就直接定义了,没有必要再申明,在申明的位置出现inline反而可能会有编译错误。

        inline对于编译器而言,只是个建议,不是强制,如下两种情况,编译器会忽略掉inline:

        (1)函数的地址被使用的时候。如通过函数指针对函数进行了间接调用。这种情况下就不得不为static inline函数生成独立的汇编码,否则它没有自己的地址。

        (2)其他一些无法展开的情况,比如函数本身有递归调用自身的行为等。

        其实,对于以上两种情况,程序员就不应该使用inline。

        2, inline

        对于gcc而言,仅有inline的函数(无static),在当前文件内部,其表现与static inline一样,在调用处展开,而对于外部文件的调用(没有static修饰,就是extern函数),跟普通全局函数一样。因此,gcc实际上在只有inline的时候,一定会为函数生成一份独立的汇编码,以便被别的模块调用。在别的文件中,这个函数跟其它全局函数没有区别。

        3, extern inline

        这是不建议使用的定义方式,gcc一定不会为这样定义的函数生成独立的汇编码。

        4, inline与gcc -On优化参数

        inline关键字仅仅是建议编译器做内联展开处理,而不是强制。在gcc编译器中,如果编译优化设置为-O0,即使是inline函数也不会被内联展开,除非设置了强制内联(__attribute__((always_in line)))属性。

        如果使用 -O0,函数定义为 inline,会有链接错误。 -O0表示inline函数不展开,还是调用,inline表示对当前文件的调用不生成独立的汇编码,因此在链接的时候,会有找不到inline函数的错误。

最后,我个人的一点感觉(不确定):使用-O3的时候,static的函数,gcc也可能自动为其加上inline属性。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C++中,`inline`是一个关键字,用于向编译器提供函数内联展开的建议。使用`inline`关键字可以告诉编译器将函数的定义直接插入到函数调用的地方,而不是通过函数调用的方式执行。 `inline`关键字的作用和优势如下: 1. 提高程序的执行效率:函数调用会引入一定的开销,包括函数调用的准备和恢复现场的操作。通过使用`inline`关键字,可以减少函数调用带来的开销,并将函数体直接嵌入到调用处,从而提高程序的执行效率。 2. 减少函数体的开销:对于较小的函数,函数体内部的代码可能相对较少。使用`inline`关键字可以避免为这些较小的函数创建独立的函数调用帧,从而减少函数体的开销。 3. 避免函数重复定义错误:当多个源文件中包含相同的`inline`函数时,编译器会将这些函数的定义嵌入到每个源文件中,而不会导致链接错误。 需要注意以下几点: - `inline`关键字只是向编译器提供了一个建议,编译器可以选择忽略该建议。编译器通常会根据函数的复杂性、大小以及其他因素来决定是否对函数进行内联展开。 - 嵌套函数、递归函数、虚函数以及包含循环或复杂控制流的函数通常不适合进行内联展开。 - 在类定义中声明的成员函数(包括定义在类内部的函数)默认是隐式的`inline`函数。 总之,`inline`关键字可以提高程序的执行效率,减少函数体的开销,并避免函数重复定义错误。然而,过度使用`inline`关键字可能会导致代码膨胀,应谨慎使用。编译器会根据具体情况来决定是否对函数进行内联展开。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值