C语言标准中对内联函数的说明:ISO/IEC 9899:2011 6.7.4 函数说明符_匈牙利认真的小菠萝的博客-优快云博客
使用方法
内联函数的定义在头文件中,并用static修饰。
// @file: hal_cq.h
static inline void fCQ_CQ_INT(U32* ptrCQArr, U08 bIntrArg, U8 bMcuSel)
{
((rCQ_INT*)ptrCQArr)->dAll = 0;
((rCQ_INT*)ptrCQArr)->bits.control_bits = bIntrArg;
((rCQ_INT*)ptrCQArr)->bits.mcu_int_sel = bMcuSel;
((rCQ_INT*)ptrCQArr)->bits.attribute = R_CQ_ATTR_INT;
}
在使用内联函数的文件中包含此头文件即可。
// @file:MEP_Main.c
#include "hal_cq.h"
int Main_FW()
{
U32 gpCqArray[1024];
U32MemSet(&gpCqArray[0], 0, 1024);
fCQ_CQ_INT(&gpCqArray[0],96,0);
return 0;
}
如何确定函数是否内联
可以通过查看汇编代码;真正内联了的函数,代码会位于调用处,不会有函数调用(入栈、出栈)动作;而没有内联的函数,会被当做普通函数,有函数调用(入栈、出栈)动作。
由上述汇编代码可知,此函数并未内联,这是因为inline是向编译器提建议,不是命令编译器,所以加inline修饰的函数是否变成内联函数,这由编译器做决定的。
在NucleiStudio的nmsis_gcc.h中有如下段:
/** \brief Recommend that function should be inlined by the compiler. */
#ifndef __INLINE
#define __INLINE inline
#endif
/** \brief Define a static function that may be inlined by the compiler. */
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
/** \brief Define a static function that should be always inlined by the compiler. */
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
#endif
函数说明符改为__STATIC_FORCEINLINE(强制内联)后,查看lst文件可以看到在代码调用处的是内联函数源码,因此该函数是内联了的。
使用内联函数的注意事项
1、使用函数指针调用内联函数将会导致内联失败。如果使用函数指针来调用内联函数,那么就需要获取inline函数的地址。如果要取得一个inline函数的地址,编译器就必须为此函数产生一个函数实体,那么就会内联失败。
2、如果函数体代码过长或者有多重循环语句,if或witch分支语句或递归时,不宜用内联。
3、如ISO/IEC 9899:201x 6.7.4小节中所说,具有外部链接的函数的内联定义,不应包含具有静态或线程存储持续时间的可修改对象的定义,也不应包含对具有内部链接的标识符的引用。
4、如果使用很多内联函数,生成的二进制文件会变大,代码空间可能不够;