关于inline

在IAR中有这样的解释 :

 

Inline assembler:内嵌汇编
    Assembler language code that is inserted directly between C statements.
Inlining:            内联
    An optimization that replaces function calls with the body of the called function. This optimization increases the execution speed and can even reduce the size of the generated code.
 
当然两者是不一样的。今天在看CMSIS的时候发现许多的inline的应用,于是乎就搜了一些,网上的资料还是很多的。但是既然找了,也就做个记录也好
 
个人理解:
  C的一个特点就是函数的模块化。编译器处理函数的调用时是用类似于中断的方式进行的。即在调用函数的之前要进行保存现场,调用结束后要进行现场的恢复(CALL 和 RET 指令)。即压栈和出栈操作。不管压栈和出栈是否复杂,都是需要耗费CPU的时间的。此时对于一些简单的函数而言,往往进行函数的调用会显得得不偿失的。所以此时就引入了inline内嵌函数的方法了。用inline进行定义后的函数在进行函数的调用的时候编译器并没有进行类似于中断处理的方法一样进行现场的保存和恢复。而是直接将函数的代码放到被调用的代码的位置之处,此时就节省了压栈与出栈的CPU的开销。这种方法很显然是有好处的。特别是对于一些函数较小的结构简单的特别适用。而其中的一类就是对define的替代。
  用define进行宏定义的时候,有一类用法是对表达式进行宏定义,这种用法的好处其实也是为了省去了POP和PUSH的开销,但是编译器对define的处理就是简单的字符替换。此时缺少的是对其类型的检查。而此时很可能就会出现一些问题。而inline定义的仍然是函数。编译器碰到函数,自然仍然会有类型检查这个功能。
  网上也有一些例子,特此摘取一个:
====================================================================================================
   内联函数就是小型函数,牺牲空间来节省函数调用的开销,一般用作比较小的函数,即函数内部没有循环、开关语句等。内联函数被发明出来就是为了取代C中的宏,因为宏是单纯的替换而没有类型检查所以经常出毛病,比如:

#define MAX(a, b) (a) > (b) ? (a) : (b)

如果你在代码中这样写:

int a = 10, b = 5;  

// int max = MAX(++a, b); // a自增了两次//
// int max = MAX(++a, b+10); // a自增了一次

a的自增次数竟然由与其比较的数字的大小来决定!?这肯定不是你想要的结果。

所以最好的办法是这样:
template <class T>
inline T max(const T& t1, const T& t2)
{
return t1 > t2 ? t1 : t2;
}

这样的话如果你这样写:

int max = max(a, b);
其实就被替换为了:
int max = a > b ? a : b;
虽然看起来宏差不多,但是比宏多了类型检查,而且内联函数使用的是真正的函数的特性,而不是宏的function-like,模拟函数的功用。

===============================================================================================
当然函数调用的好处是能够节省空间,函数内部的变量在使用完后会自动退出舞台,释放内存。但是用inline的内联函数,会增加代码空间,使用不当,会造成代码的膨胀,应小心使用。一般只用在可以直接进行返回一些表达式的值的场合。当带有if switch for 等结构的时候一般不考虑使用。
 

posted on 2013-05-29 10:46  展翅的小鸟  阅读(237)  评论(0编辑  收藏  举报

导航