宏代码与内联函数区别(转)

上一篇 / 下一篇  2012-07-18 21:58:19 / 个人分类:C\C++

语言支持关系: 
C  宏代码 
C++ 宏代码 内联函数 

宏代码本身不是函数,但使用起来象函数.预处理器用复制宏代码的方式代替函数调用,省去了参数压栈、生成汇编语言的CALL调用、返回参数、执行return 等过程,从而提高了速度.使用宏代码最大的缺点是容易出错,预处理器在复制宏代码时常常产生意想不到的边际效应. 
于任何内联函数,编译器在符号表里放入函数的声明(包括名字、参数类型、返回值类型).如果编译器没有发现内联函数存在错误,那么该函数的代码也被放入符号表里.在调用一个内联函数时,编译器首先检查调用是否正确(进行类型安全检查,或者进行自动类型转换,当然对所有的函数都一样).如果正确,内联函数的代码就会直接替换函数调用,于是省去了函数调用的开销.这个过程与预处理有显著的不同,因为预处理器不能进行类型安全检查,或者进行自动类型转换.假如内联函数是成员函数,对象的地址(this)会被放在合适的地方,这也是预处理器办不到的. 

宏定义是预处理器在代码优化时直接替换的,而内联函数是在编译期间插入代码.宏定义替换比内联函数执行得早

内联函数使用方法: 
关键字inline 必须与函数定义体放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用. 
正确使用方法
void Foo(int x, int y); 
inline void Foo(int x, int y) // inline 与函数定义体放在一起 

… 

错误使用方法: 
inline void Foo(int x, int y); // inline 仅与函数声明放在一起 
void Foo(int x, int y) 

… 
}
.在内联函数内不允许用循环语句和开关语句。 

  如果内联函数有这些语句,则编译将该函数视同普通函数那样产生函数调用代码,递归函数(自己调用自己的函数)是不能被用来做内联函数的。内联函数只适合于只有1~5行的小函数。对一个含有许多语句的大函数,函数调用和返回的开销相对来说微不足道,所以也没有必要用内联函数实现。


2.显式内联函数和隐式内联函数

   a.在类声明的内部声明,而在类声明外部定义叫做显式内联函数,如:

  class display

  { 

  int t;

  public:

  void output(void)

  }


display object;

  inline void display::output(void)

  {

  cout << "i is " << i <<"\n";

  }

b.在类声明的内部定义,叫做隐式内联函数,如:

  class display

  { 

  int t;

  public:

  inline void output(void)

  {cout<<"i is "<< i << "\n";}

  } 


慎用内联
内联能提高函数的执行效率,为什么不把所有的函数都定义成内联函数?
如果所有的函数都是内联函数,还用得着“内联”这个关键字吗?

内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。以下情况不宜使用内联:

(1)如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。
(2)如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。
类的构造函数和析构函数容易让人误解成使用内联更有效。要当心构造函数和析构函数可能会隐藏一些行为,如“偷偷地”执行了基类或成员对象的构造函数和析构函数。所以不要随便地将构造函数和析构函数的定义体放在类声明中。

一个好的编译器将会根据函数的定义体,自动地取消不值得的内联(这进一步说明了inline不应该出现在函数的声明中)。



TAG:

 

评分:0

我来说两句

日历

« 2024-04-16  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 54619
  • 日志数: 40
  • 建立时间: 2012-07-17
  • 更新时间: 2012-10-01

RSS订阅

Open Toolbar