内联函数

一、背景:函数在源代码->预处理->编译和优化->生成目标文件->链接->可执行程序或镜像文件时。

  函数的存在形式:

  1.1.普通函数:在编译时是将函数代码放在指定位置,其他函数调用此函数时,进行跳转地址,参数通过寄存器进行传递。

  1.2.内联函数:在预处理时将函数体代码直接替换函数调用处,不进行跳转地址,不进行参数通过寄存器进行传递。(实质与宏定义一样)

  注意:能否形成内联函数,需要看编译器对该函数定义的具体处理。(C99和GNU C支持)

二、特点与环境

  2.1.1.优点

    消除函数调用和返回所带来的开销(寄存器存储和恢复),且编译器会将调用函数的代码和函数本身一起进行优化。

  2.1.2.缺点

    代码变长,占用更多的内存空间或者占用更多的指令缓存。

  2.2.1.适用环境

    对时间要求较高,长度较短的函数。

  2.2.2.不适用环境

    函数较大,反复被调,时间上无特殊限制。

三、内联C格式

  内联函数是指用inline关键字修饰的函数。

  一般在头文件中定义,如果一个内联函数仅在某个源文件中使用,也可以定义在该文件的开始处。

  且前缀static(编译时不会为内联函数单独建立一个函数体)

  3.1.C语言中实现

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
 
static inline void acodec_regsetbit(
    
unsigned long value,
    
unsigned long offset,
    
unsigned long addr)
{
    
unsigned long t, mask;

    mask = 
1 << offset;
    t = readl(addr);
    t &= ~mask;
    t |= (value << offset) & mask;
    writel(t, addr);
}

  3.2.C++中实现

    3.2.1.类中定义inline函数

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
 
class ClassName
{
    .....
    ....
    INT GetWidth()
    {
        
return m_lPicWidth;
    }; 
// 如果在类中直接定义,不需要用inline修饰,编译器自动化为内联函数
    .... //此说法在《C++ Primer》中提及
    ....
}

     3.2.2.类外定义inline函数

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
 
class Account {
public:
Account(
double initial_balance) { balance = initial_balance; } //与1相同
double GetBalance(); //在类中声明
double Deposit( double Amount );
double Withdraw( double Amount );
private:
double balance;
};
inline double Account::GetBalance() { return balance; } //在类外定义时添加inline关键字
inline double Account::Deposit( double Amount ) { return ( balance += Amount ); }
inline double Account::Withdraw( double Amount ) { return ( balance -= Amount ); }

    注意:

    1.inline说明对编译器来说只是一种建议,编译器可以选择忽略这个建议。比如,你将一个长达1000多行的函数指定为inline,编译器就会忽略这个inline,将这个函数还原成普通函数。
    2、在调用内联函数时,要保证内联函数的定义让编译器"看"到,也就是说内联函数的定义要在头文件中,这与通常的函数定义不一样。但如果你习惯将函数定义放在CPP文件中,或者想让头文件更简洁一点,可这样做:

 

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
 
#ifndef SOMEINLINE_H
#define SOMEINLINE_H
Type Example(
void);
//........其他函数的声明
#include"SomeInlie.cpp" //源文件后缀名随编译器而定
#endif
//SomeInline.cpp中
#include"SomeInline.h"
inline Type Example(void)
{
//..........
}
//...............其他函数的定义

四、内联汇编

  4.1.前提

    知道对应体系结构,才能使用此功能。

  4.2.格式

    asm volatile(“....”);

    举例:

      asm volatile("rdtsc" : "=a" low, "=d" (high));

  4.3.适用环境

    偏近体系结构的底层或对执行时间要求严格。

五、产生原因

  优点:

    C语言是一个效率很高的语言,这种宏定义在形式及使用上像一个函数,但它使用预处理器实现,没有了参数压栈,代码生成等一系列的操作,因此,效率很高。

    C++中引入了类及类的访问控制,这样,如果一个操作或者说一个表达式涉及到类的保护成员或私有成员,你就不可能使用这种宏定义来实现(因为无法将this指针放在合适的位置)。为了取代这种表达式形式的宏定义,inline消除了宏定义的缺点,同时又很好地继承了宏定义的优点。

  缺点:

     因为实际操作为预处理器符号表中的简单替换,因此它不能进行参数有效性的检测,也就不能享受C++编译器严格类型检查的好处,另外它的返回值也不能被强制转换为可转换的合适的类型。

posted @ 2017-11-01 20:16  扑克face  阅读(218)  评论(0编辑  收藏  举报