本站动态:
inline的一种特殊用法
作者:shosh 日期:2009-02-24
曾经我在一个c文件里用几个函数实现了一个比较Common的Functions,并提供一个对应的h文件让使用者#include。接口如下:
//please do not call these functions directly
int WriteTrace(int nLevel, char* pFile, int nLine, char* format, ...);
void EndWriteTrace(void);
这个Common的功能会在很多地方被人调用,但是它只在target端(真实运行环境)运行,而在simulator端(模拟运行环境,为方便调试加快编程速度而引入的模拟的运行环境)不需要/无法运行该功能。所以我定义了下面一些宏,让用户通过宏来调用这些提供出来的接口:
//please use these macros instead
#ifdef AEE_SIMULATOR //don't let it run in simulator
#define TRACE_FILE
#define END_TRACE
#else
#define TRACE_FILE WriteTrace
#define END_TRACE EndWriteTrace
#endif
为了方便描述问题,模拟地写了一段代码:
- int WriteTrace(int nLevel, int add)
- {
- return nLevel + add;
- }
- void EndWriteTrace(void)
- {
- return;
- }
- //#define AEE_SIMULATOR
- #ifdef AEE_SIMULATOR //don't let it run in simulator
- #define TRACE_FILE
- #define END_TRACE
- #else
- #define TRACE_FILE WriteTrace
- #define END_TRACE EndWriteTrace
- #endif
- int main(void)
- {
- TRACE_FILE(1, 3);
- END_TRACE();
- return 0;
- }
当AEE_SIMULATOR未被定义时,那么TRACE_FILE就是WriteTrace,END_TRACE就是EndWriteTrace,也就是前文提到的在target端运行,这样不存在任何问题,可以无错误无警告通过编译。但是如果定义了AEE_SIMULATOR,也就是想编译出在simulator上运行的代码,会发现会有一个错误。错误原因很容易发现,因为main函数体内第二行语句END_TRACE();宏展开后的代码是();,这句代码自然不可以编译通过了。那第一行TRACE_FILE(1, 3);宏展开后是(1, 3);为什么没有错误也没有警告呢?因为(1, 3);是C语言中的表达式(逗号运算,表达式的值是3),就算是(1); 也是C语言中的表达式(表达式的值是1),没有错误。因为(void);不是表达式(void不是值),所以就算将END_TRACE()改成END_TRACE(void)也是不能通过编译的。
要解决这样的问题,我最先想到了两种解决方案:
1、给END_TRACE添加一个无效的参数。对于target端,多了一个无效参数,有一定的资源浪费,不过影响小到可以忽略。
2、在simulator上实现一个空函数void funNum(void),将END_TRACE定义为该函数的函数名funNum,这样做对target端无任何影响,但是simulator端多了一个空函数,加大了编译出来的文件,不过影响同样很小。关键是要添加空函数void funNum(void)的实现,当然最适合放在我提供的那个c文件里。不过这样需要增加工作量,在simulator的编译工程中也需要将该c文件编译进来,需要修改到dsp文件,而实际上我们不希望这样(在simulator上只需要包含h文件即可编译通过了,那c文件不需要编译,也不需要加到工程中)。
后来想到了一个完美的方法,既解决了问题,又没有上面的问题。那就是在h文件中实现空函数void funNum(void),不过得加关键字__inline。
- //-------------in .c file------------------------//
- int WriteTrace(int nLevel, int add)
- {
- return nLevel + add;
- }
- void EndWriteTrace(void)
- {
- return;
- }
- //---------in .h file that for users to include------//
- __inline void FuncName(void)
- {
- //this function's just empty for special usage
- }
- //#define AEE_SIMULATOR
- #ifdef AEE_SIMULATOR //don't let it run in simulator
- #define TRACE_FILE
- #define END_TRACE FuncName
- #else
- #define TRACE_FILE WriteTrace
- #define END_TRACE EndWriteTrace
- #endif
- //------------in test.c file------------//
- int main(void)
- {
- TRACE_FILE(1, 3);
- END_TRACE();
- return 0;
- }
引用内容这句话有些不妥,因为即使是直接的函数调用,若函数的参数为void,调用时是不能够在括号里加行void的。
上一篇
下一篇

文章来自:
Tags:
相关日志:
回复







#ifdef AEE_SIMULATOR
#define END_TRACE()
#else
#define END_TRACE EndWriteTrace
#endif
这样不管什么用的是什么,都可以调用END_TRACE();了。
这里的EndWriteTrace省略了函数体中的代码,并不是空函数。