聊聊预编译那些事——
平时看代码总能看到写陌生的东西。它们与应用代码无关,却能帮助我们,很好的管理代码,或者按照我们预想的去编译处理。
为此,编译器就提供了这些东西。。(一下就是我遇到的不常用,又或者比较重要的用法!!)
内置的macro:
先介绍几个编译器内置的宏定义,这些宏定义不仅可以帮助我们完成跨平台的源码编写,灵活使用也可以巧妙地帮我们输出非常有用的调试信息。
ANSI C标准中有几个标准预定义宏(也是常用的):
__LINE__:在源代码中插入当前源代码行号;
__FILE__:在源文件中插入当前源文件名;
__DATE__:在源文件中插入当前的编译日期
__TIME__:在源文件中插入当前编译时间;
__STDC__:当要求程序严格遵循ANSI C标准时该标识被赋值为1;
__cplusplus:当编写C++程序时该标识符被定义。
编译器在进行源码编译的时候,会自动将这些宏替换为相应内容。
<预编译宏一>
_FILE_
它指的是,包含该宏_FILE_所在文件的文件路径名。 数据类型应该是 char const*
_FUNCTION_
它指的是,包含该宏_FUNCTION_所在的函数的——函数名。 数据类型 char const*
_LINE_
又指,包含_LINE_这行的代码,所在的行号。 数据类型 int
/*有用用法:当我们调试的时候,我想知道我的函数有没有编译。比如他被外部宏层层控制,这个时候不方便知道他有没有编译有没有执行。
我们可以这样:printf("FILE=%s,Function=%s, Line=%d",_FILE_, _FUNCTION_, _LINE_)。*/
案例: zegbee中定义 #define st(x) do{x}while(_LINE_==-1)
#define SET_REGS() st(ioreg1=0; ioreg2=0;)
体格醒,类似宏定于多条语句,记得用大括号包好; 运算表达式,也应该小括号,包好。
。。。当然想要知道哪些代码会被编译,可以如下:
<预编译宏二>
#error 。。。。
造成编译错误,代码是不能编译通过咯! (大小写好像都行,在IAR上试过,不知其他怎么样 #ERROR 。。)
/*#error “Complie stoped here !!”*/
#warning 。。。。
让编译器发错警告信息。
/*#warning "你正在编译这段代码" */
<预编译宏三>
。。。(待续)
IAR编译:如何将函数编译在内存中运行。
#if defined (__ICCARM__)
__ramfunc
#endif
static void funcA();//函数申明
#if defined (__ICCARM__)
__ramfunc
#endif
。
。
#if defined (__ICCARM__)
__ramfunc
#endif
static void funcA() //函数定义
{
。。。
}
#if defined (__ICCARM__)
__ramfunc
#endif
这样代码在执行时就能搬到RAM中运行,增加速率。缺点占内存。
如何将数据结构按照 指定字节对其?
#pragma(1)//当前指定单字节对其
struct student{
unsigned char age;
unsigned char nane[8];
unsigned short score_sum;
}
#pragram ()