赛迪网 > IT技术 C/C++ > 文章
  IT资讯搜索
 
IT产品搜索
[程序开发][网管世界][网络安全][数据库技术]
[操作系统][嘉宾聊天·在线访谈][活动集锦]
[精彩专题][Symantec专区][订阅IT技术周刊]
[开发论坛][网管论坛][安全论坛][数据库论坛]
[操作系统论坛][Sybase专区][IBM dW技术专区]
[病毒求助][病毒与漏洞播报][文档·源码下载]

C++箴言:理解inline化的介入和排除 (2)

发布时间:2006.03.14 06:20     来源:Blog    作者:sixth

max 是一个模板的事实引出一个观察结论:inline 函数和模板一般都是定义在头文件中的。这就使得一些程序员得出结论断定函数模板必须是 inline。这个结论是非法的而且有潜在的危害,所以它值得我们考察一下。 inline 函数一般必须在头文件内,因为大多数构建环境在编译期间进行 inline 化。为了用被调用函数的函数本体替换一个函数调用,编译器必须知道函数看起来像什么样子。(有一些构建环境可以在连接期间进行 inline 化,还有少数几个——比如,基于 .NET Common Language Infrastructure (CLI) 的控制环境——居然能在运行时 inline 化。然而,这些环境都是例外,并非规则。inline 化在大多数 C++ 程序中是一个编译时行为。)

  模板一般在头文件内,因为编译器需要知道一个模板看起来像什么以便用到它时对它进行实例化。(同样,也不是全部如此。一些构建环境可以在连接期间进行模板实例化。然而,编译期实例化更为普遍。) 模板实例化与 inline 化无关。如果你写了一个模板,而且你认为所有从这个模板实例化出来的函数都应该是 inline 的,那么就声明这个模板为 inline,这就是上面的 std::max 的实现被做的事情。但是如果你为没有理由要 inline 化的函数写了一个模板,就要避免声明这个模板为 inline(无论显式的还是隐式的)。inline 化是有成本的,而且你不希望在毫无预见的情况下遭遇它们。我们已经说到 inline 化是如何引起代码膨胀的,但是,还有其它的成本,过一会儿我们再讨论。

  在做这件事之前,我们先来完成对这个结论的考察:inline 是一个编译器可能忽略的请求。大多数编译器拒绝它们认为太复杂的 inline 函数(例如,那些包含循环或者递归的),而且,除了最细碎的以外的全部虚拟函数的调用都不会被 inline 化。不应该对这后一个结论感到惊讶。虚拟意味着“等待,直到运行时才能断定哪一个函数被调用”,而 inline 意味着“执行之前,用被调用函数取代调用的地方”。如果编译器不知道哪一个函数将被调用,你很难责备它们拒绝 inline 化这个函数本体。

  所有这些加在一起,得出:一个被指定的 inline 函数是否能真的被 inline 化,取决于你所使用的构建环境——主要是编译器。幸运的是,大多数编译器都有一个诊断层次,在它们不能 inline 化一个你提出的函数时,会导致一个警告。

  有时候,即使当编译器完全心甘情愿地 inline 化一个函数,他们还是会为这个 inline 函数生成函数本体。例如,如果你的程序要持有一个 inline 函数的地址,编译器必须为它生成一个 outlined 函数本体。他们怎么能生成一个指向根本不存在的函数的指针呢?再加上,编译器一般不会对通过函数指针的调用进行 inline 化,这就意味着,对一个 inline 函数的调用可能被也可能不被 inline 化,依赖于这个调用是如何做成的:

inline void f() {...} // assume compilers are willing to inline calls to f

void (*pf)() = f; // pf points to f
...

f(); // this call will be inlined, because it’s a "normal" call
pf(); // this call probably won’t be, because it’s through
// a function pointer

<<上一页 1 2 3 4 下一页>>


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· VC++中进程与多进程管理的方法 (03-10) · 解决出现的LNK2005“符号已定义”错误 (03-10)
· 取长补短:Simulink与VC++6.0接口比较 (03-10) · C++箴言:如何访问模板化基类中的名字 (03-09)
· 也玩视觉效果:VC++编程实现仿真火焰 (03-09) · 体验C++中接口与实现分离的技术 (03-09)
· Stan Lippman:C++/CLI全景体验 (03-08) · 用VC++制作播放AVI视频流的动画按钮 (03-07)
· Visual C++ 6.0编程实现打印功能 (03-02) · VC++串口编程之短信应用开发 (02-24)
  客户需求反馈表
* 姓  名:
更多资料  了解方案  认识厂商
* 单位名称:
* 联系电话:
* 电子邮件:
  赛迪推荐  
  手机·资费 ·新品·导购·评测·手机资费·宽带
手机搜索  诺基亚 N73 MOTO Z6
  IT产品 ·笔记本·台式机·服务器·打印·投影
IT产品搜索 
  IT技术 ·开发·网管·安全·数据库·操作系统
  信息化 ·热点·专题·访谈·周刊·方案案例
[政务][电信][金融][农业][制造业][中小企业]
[CIO][ERP][协同][IT管理][中间件][电子商务]
[政策][地方][专家][评估][辞典][博客][社区]
· 专题:一路畅通构想曲——让出行不再遭遇堵车
· CIO工作亲历:企业ERP选型不能忽视"选人关"
· 综述:信息化建设给中国监狱带来的各种变化
· 金融业风险管理和法规遵从有五点需考虑的因素
· 保险业CIO关注:该如何建立统一高效的CRM体系
· 调查显示:多数CIO对IT规划仍存在困惑和误解
  博客·论坛 ·曾剑秋·项立刚·Java学习·网管