###########################################################################################################
#ifndef BOOT_ISDIGIT_H
#define BOOT_ISDIGIT_H
static inline int isdigit(int ch)
{
return(ch >= '0') && (ch <= '9');
}
static inline int isxdigit(int ch)
{
if(isdigit(ch))
return true;
if((ch >= 'a') && (ch <= 'f'))
return true;
return(ch >= 'A') && (ch <= 'F');
}
#endif
###########################################################################################################
转自:http://hi.baidu.com/beibeiboo/blog/item/cbea8c03191c027e3812bb72.html
看kernel,随处可见inline.说实话,还没写过带inline的东东呢,今天也看看到底是什么高深的玩意.
在c中,为了解决一些频繁调用的小涵数大量消耗栈空间或是叫栈内存的问题,特别的引入了inline修饰符,表示为内联涵数。
可能说到这里,很多人还不明白什么是栈空间,其实栈空间就是指放置程式的局部数据也就是函数内数据的内存空间,在系统下,栈空间是有限的,假如频繁大量的使用就会造成因栈空间不足所造成的程式出错的问题,涵数的死循环递归调用的最终结果就是导致栈内存空间枯竭。
下面我们来看一个例子
#include <stdio.h>
inline char* dbtest(int a); //函数原形声明为inline即:内联涵数
int main()
{
int i = 0;
for (i=1;i<=10;i )
{
printf("%d is %s\n",i,dbtest(i));
}
return 0;
}
char* dbtest(int a)//这里不用再次inline,当然加上inline也是不会出错的
{
return (a%2>0)?"奇":"偶";
}
上面的例子就是标准的内联涵数的用法,使用inline修饰带来的好处我们表面看不出来,其实在内部的工作就是在每个for循环的内部任何调用 dbtest(i)的地方都换成了(i%2>0)?"奇":"偶"这样就避免了频繁调用函数对栈内存重复开辟所带来的消耗。
说到这里很多人可能会问,既然inline这么好,还不如把所谓的函数都声明成inline,嗯,这个问题是要注意的,inline的使用是有所限制的,inline只适合涵数体内代码简单的涵数使用,不能包含复杂的结构控制语句例如while switch,并且不能内联函数本身不能是直接递归函数(自己内部还调用自己的函数)。
说到这里我们不得不说一下在c语言中广泛被使用的#define语句,是的define的确也能够做到inline的这些工作,但是define是会产生副作用的,尤其是不同类型参数所导致的错误,由此可见inline有更强的约束性和能够让编译器检查出更多错误的特性,在c 中是不推荐使用define的。
###########################################################################################################
转自:http://www.chineselinuxuniversity.net/articles/49111.shtml
大学在教科书上学习过inline函数,定义为inline函数之后,会省去函数调用的开销,直接嵌套汇编代码,取代函数调用,提高效率。工作后项目中也很少用到inline来定义函数,近几天在研读google的google c++ style guide,发现之前自己对inline函数的认识太过肤浅了,这里学习总结一下。
1、inline函数不要超过10行代码,且不能包含循环、switch、if语句
2、在一个c文件中定义的inline函数是不能在其它c文件中直接使用,google推荐把inline函数定义在**-inl.h头文件中。
3、不要过度使用inline函数定义,尤其对大函数来说
上面三点说明如何正确的使用inline函数,我以前的时候对inline理解不透彻,使用inline的方式不正确,但现在编译器够先进,能保证错误的inline定义也可以正确编译、运行。可能会有性能的缺失。
我在F14(gcc 版本 4.5.1 20100924 (Red Hat 4.5.1-4) (GCC))上做了个实验:
1、当inline函数超过10行,并且包含了循环、switch语句后gcc会执行inline语义,将inline函数汇编嵌入到main函数中。
//gcc n.c -O2 -S
#include <stdio.h>
#include <string.h>
//inline int inc_inline(volatile int *j);
inline int inc_inline(volatile int *j)
{
for (;*j < 100; (*j)++)
{
*j += 2;
(*j)++;
}
switch (*j)
{
case 1:
(*j)++;
break;
case 2:
(*j)++;
break;
default:
break;
}
return (*j)++;
}
int main(int argc, char *argv[])
{
volatile int i = 0;
inc_inline(&i);
printf("i;%d\n", i);
return 0;
}
2、当我把inline函数的定义放到另一个c文件中,在main函数文件中声明此函数,此时inline函数不生效,gcc编译出的汇编使用call进行正常的函数调用。
//gcc n.c a.c -O2 -S
3、当我们过度使用inline函数,会造成程序文件变大,性能降低。程序文件变大是肯定的,但为什么性能会降低呢,inline不是为了提高性能吗?使用的方式不正确性能不能提高,反而会下降。现在的CPU上都有cache,紧凑的代码在chache中保存的时间更长,这样cache命中的机会更高。
如果某个A函数未定义为inline,并且被很多其它函数调用,那个这个A函数很大的可能会长期被保存在cahe中,这样CPU对代码的执行速度会提高很多。如果A函数被定义为了inline函数,代码分散各个调用函数中,这样每次指定都不命中都需要去内存把代码拷贝到cache中,然后执行,造成很大的抖动。
更深一层的理解,当函数整个函数编译为的汇编代码,函数调用的上下文切换占用了大多的时间的时候,可以考虑把此函数定义为inline函数。
###########################################################################################################