static和inline解析

我通过看 源代码发现:
static inline void sema_init (struct semaphore *sem, int val)
{

   
   
   

/*
*        *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
*
* i'd rather use the more flexible initialization above, but sadly
* GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well.
*/
        atomic_set(&sem->count, val);
        sem->sleepers = 0;
        init_waitqueue_head(&sem->wait);
}

static inline void init_MUTEX (struct semaphore *sem)
{
        sema_init(sem, 1);
}
sema_init是一个static型函数,init_MUTEX也是static型函数,可是我们在编驱动程序时总是在用sema_init,init_MUTEX.
我不明白,一个static型函数除了在它声明的原程序文件中可见外,其他地方是不可见的,难道说我们include了之后在我们这个主程序文件中又可见了,且又是static型????


如果一个函数既是inline又是static,如果所有对函数的调用都能被展开在调用者里面,并且这个函数的地址从来没有被使用过,那么这种情况下不存在对这个函数本身汇编代码的引用。这时,GNU CC实际上并不输出这个函数的汇编代码,除非加选项“-fkeep-inline-functions”。存在一些由于各种原因不能被展开的调用(比如,在函数声明前的调用不能被展开,定义中的递归调用同样也不行)。如果存在未展开的函数调用,那么这个函数象通常一样被编译生成汇编代码。如果这个函数被通过地址引用,那么这个函数也必须象一般函数那样被编译生成,因为那样的引用不能够被展开(inlined)。
当一个inline函数不是static时,那么编译器必须假设其他源程序中可能存在调用,因为一个全局符号只能被定义一次,所以这个函数在其他源程序中不能被定义,于是那里的调用不能够被展开。因此,一个非static的inline函数总是同普通函数一样被编译生成。
如果函数声明中同时使用了inline和extern,那么这个定义只被用来inline展开。这个函数体的汇编代码从来都不会被编译生成,即使你显示引用了它的地址,显示引用的地址变成一个外部引用,就像你仅仅声明了这个函数,而没有定义它一样。
inline和extern的结合几乎达到一个宏定义的效果。使用它的方法是在头文件中使用这些关键字写出函数定义,同时在库文件中放入另一份函数体定义的拷贝(没有inline和extern)。在头文件中的定义将会使大部分对函数的调用被inline展开。如果存在对这个函数的使用,它们将会引用库中的单一拷贝。

你可能感兴趣的:(static和inline解析)