蓝点工坊(http://www.bluedrum.cn) 创始人,App和嵌入式产品开发。同时也做相应培训和外包工作。 详细介绍 http://pan.baidu.com/s/1y2g88
全部博文(311)
分类: C/C++
2010-05-08 15:31:20
Andrew Huang
一个学员拿了这样一个定义问我含义,我解释了后,看一下这个对于C预处理和gcc的细节问题还是很典型。因此跟大家分享一下。
|
1.定义一个结构 struct cmd_tbl,有两个成员,第一个名字是name.第二是cmd,是一个函数指针。
2.宏cmd_section 定义是 __attribute__ ((unused,section (".g_boot_cmd"))),这个是gcc的特殊用法__atribute__是用来定义一些特性属性。用处在后面结构生成后再一并解释
3宏G_BOOT_CMD定义比较复杂了,这里采用\来做换行符,来用多行定义宏体。
4.这个宏有两参数cmd_name,cmd_cmd.
5.##在宏定义表示把宏变量联接成两个字符串,形成一个新的符号名字(如变量名,函数名)。主要用于变量名的定义,这样在用同一个宏里可以定义出不同变量
6.#在宏定义表示把宏变量字符串化,换句话说宏变量在C源码是怎么样的,将会转成对应字符串。如 #define PRINT_INT(e) printf("%s=%d\n",#e,e),这里的#e就是用把宏变量转成对应名字.
注意一下如果宏变量是char *类型,用#宏开时,与变量对应值无关,#只取显示的名字。比如
char * tmp = "hxy"; #define PRINT_STR(e) printf("%s=%s\n",#e,e)
PRINT_STR(tmp);中#e,输出是"tmp",而不是"hxy";
要注意#是转成字符串,##是转成一个符号,关于#和##具体用法。可以参见如下更为简单代码b
|
g_boot= tmp
g_boot_hxy=tmp
7..name = ...,和 .cmd = ....是gcc的结构初始化的特殊用法。这样可以不需要理会结构成员定义顺序,可以用 .成员名= 成员值 来指定名字来定义,这样结构成员位置调整后不需改变结构代码。另外用成员名来初始化。可以减少出错可能性。标准C只能采用{}来定义了
cmd_tbl boot = { "boot",boot_fn }; //标准C用法
cmd_tbl boot = { .cmd = boot_fn, .name ="boot"} ; //gcc 扩展用法
8.综合所述, G_BOOT_CMD是定义一个全局的cmd_tbl.并且完成初始化。这里可以谈cmd_section的用法了。全局变量默认是放在数据段里,section (".g_boot_cmd")表示这个变量链接在.g_boot_cmd这个自定义段中