c++和c语言的inline关键字对比

本文探讨了C++中内联函数的特性及其对程序性能的影响。通过分析《C++沉思录》中的实例,解释了为何保留Trace对象在不进行跟踪时几乎不增加额外开销。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

其实我一直比较喜欢C语言,对C++的了解少之又少,但是最近由于需要翻看起C++的书籍来。在C++沉思录当中,看到了这样一句话:“我还指出,由于这些成员函数定义在Trace类自身的定义内,C++会内联扩展它们,所以就使得即使在不进行跟踪的情况下,在程序中保留Trace对象也不必付出许多代价。——Koenig,《C++沉思录中文版》,page2”。K先生所举例的代码如下所示:

 1 class 
 2 Trace{
 3 public :
 4            Trace(){noisy = 0;}
 5            void print(char *s){if(noisy) printf("%s,"s);}     
 6            void on(){noisy = 1;}
 7            void off(){noisy = 0;} 
 8 
 9 private:
10            noisy = 1;
11 }

其实这段代码风格并不是所提倡的(函数的声明和定义其实应该分隔开的),当然K先生这里的目的是举个例子说明问题。

但是这里确实引起了我的疑惑,为什么K先生说“即使在不跟踪的情况下,在程序中保留Trace对象也不必付出许多代价”?按理说,这种把函数定义直接写在类内部的方式直接导致了函数的内联,而内联确实膨胀程序,因此我产生了疑惑,这里先埋下伏笔,在知识梳理完毕后尝试解惑故。


下面的知识引用自优快云博客,http://blog.youkuaiyun.com/lidh04/article/details/3795802和http://blog.youkuaiyun.com/zhangchao3322218/article/details/8099747。

首先在C语言中也是存在inline的,这里的说明是针对gcc 编译器的。在gcc 中,有三种方式的内联,分别为static inline,inline,extern inline,下面分开介绍:

1.inline。定义的说法:这是一个针对函数定义的关键字(注意并非针对声明),用于对编译器的建议,当然编译器有理由拒绝,其作用为不专门为其在调用处产生汇编代码,只是像宏那样进行展开。

注意,以下情况不在上述讨论的范围内:

一、回调

二、递归

例外情况的原因请读者自行思考。而且,被这样生命的函数可以在文件外被调用,像这样 

extern func();

但是需要注意的是,不可以出现这种情况:

extern inline function();//这是不对的

这是我们下面讨论的extern inline,使用情况很狭窄,请注意。

2.static inline 。可以理解为static和inline这两种属性的叠加。故而,相对于inline来讲,static限制了这种函数只能在被定义的文件中使用,不可以被extern。

3.extern inline。这个不能想当然的理解为extern 和 inline 属性的叠加。实际上,gcc的extern inline 函数只能被内联,并不会产生出独立的汇编代码,即使出现了上面提到的两种意外;而且,extern inline 允许在同一个文件中出现重名函数。

但是我们一般没有理由使用这样一种东西,其存在的意义我现在还没有搞明白。

 

下面来看一下在C++当中的inline。

其实这两种语言的的inline很相似的,C++中比C中多的那一部分应该使我们在开篇提到的Class的内部会自动将已经定义好的函数内联,但是这个并不是值得提倡的。在编译的时候,inline函数省去了函数调用的开销(esp,ebp,寄存器数据改变,局部性改变,上下文切换等等),因此规模较小的inline函数会增加性能。

 

那么我们回到刚开始的疑惑,尝试着解答。

回顾一下,我的疑惑是K先生的“在程序中保留Trace对象也不必付出许多代价”,产生疑惑的原因是我对于内联的理解:在调用处进行函数的展开,导致程序的膨胀。

但是由于这里被内联的函数很小,根本和膨胀谈不上关系,在我们不回收Trace对象的时候,也不会产生太大的浪费,也就是K先生所言“代价”。


 

转载于:https://www.cnblogs.com/mickey-nan/p/4122297.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值