欢迎来到天天文库
浏览记录
ID:1480008
大小:138.00 KB
页数:12页
时间:2017-11-11
《c语言gnu扩展语法》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、GNUC9条扩展语法GNCCC是一个功能非常强大的跨平台C编译器,它对标准C语言进行了一系列扩展,以增强标准C的功能,这些扩展对优化、目标代码布局、更安全的检查等方面提供了很强的支持。本文把支持GNU扩展的C语言称为GNUC。Linux内核代码使用了大量的GNUC扩展,以至于能够编译Linux内核的唯一编译器是GNUCC,以前甚至出现过编译Linux内核要使用特殊的GNUCC版本的情况。本文是对Linux内核使用的GNUC扩展的一个汇总,希望当你读内核源码遇到不理解的语法和语义时,能从本文找到一个初步的解答,更详细的信息可以查看gcc.info
2、。文中的例子取自Linux2.4.18。1、零长度和变量长度数组GNUC允许使用零长度数组,在定义变长对象的头结构时,这个特性非常有用。例如://include/linux/minix_fs.hstructminix_dir_entry{_u16inode;charname[0];};结构的最后一个元素定义为零长度数组,它不占结构的空间。在标准C中则需要定义数组长度为1,分配时计算对象大小比较复杂。GNUC允许使用一个变量定义数组的长度,比如:intn=0;scanf("%d",&n);intarray[n];2、case范围GNUC允许在一个
3、case标号中指定一个连续范围的值,例如://arch/i386/kernel/irq.ccase'0'...'9':c-='0';break; case'a'...'f':c-='a'-10;break; case'A'...'F':c-='A'-10;break;3、语句表达式GNUC把包含在括号中的复合语句看做是一个表达式,称为语句表达式,它可以出现在任何允许表达式的地方,你可以在语句表达式中使用循环、局部变量等,原本只能在复合语句中使用。例如://include/linux/kernel.h#definemi
4、n_t(type,x,y)({type__x=(x);type__y=(y);__x<__y?__x:__y;})//net/ipv4/tcp_output.cintfull_space=min_t(int,tp->window_clamp,tcp_full_space(sk));复合语句的最后一个语句应该是一个表达式,它的值将成为这个语句表达式的值。这里定义了一个安全的求最小值的宏,在标准C中,通常定义为:#definemin(x,y)((x)<(y)?(x):(y))这个定义计算x和y分别两次,当参数有副作用时,将产生不正确的结果,使用语句
5、表达式只计算参数一次,避免了可能的错误。语句表达式通常用于宏定义。4、typeof关键字使用前一节定义的宏需要知道参数的类型,利用typeof可以定义更通用的宏,不必事先知道参数的类型,例如://include/linux/kernel.h#definemin(x,y)({/consttypeof(x)_x=(x); /consttypeof(y)_y=(y); /(void)(&_x==&_y); /_x<_y?_x:_y;})这里typeof(x)表示x的值类型,第3行定义了一个与x类型相同的局部变量
6、_x并初使化为x,注意第5行的作用是检查参数x和y的类型是否相同。typeof可以用在任何类型可以使用的地方,通常用于宏定义。5、可变参数宏在GNUC中,宏可以接受可变数目的参数,就象函数一样,例如://include/linux/kernel.h#definepr_debug(fmt,arg...)printk(KERN_DEBUGfmt,##arg)这里arg表示其余的参数,可以是零个或多个,这些参数以及参数之间的逗号构成arg的值,在宏扩展时替换arg,例如:pr_debug("%s:%d",filename,line)扩展为printk
7、("<7>""%s:%d",filename,line)使用##的原因是处理arg不匹配任何参数的情况,这时arg的值为空,GNUC预处理器在这种特殊情况下,丢弃##之前的逗号,这样pr_debug("success!/n")扩展为 printk("<7>""success!/n")注意最后没有逗号。6、标号元素标准C要求数组或结构变量的初使化值必须以固定的顺序出现,在GNUC中,通过指定索引或结构域名,允许初始化值以任意顺序出现。指定数组索引的方法是在初始化值前写'[INDEX]=',要指定一个范围使用'[FIRST...LAST]='的
8、形式,例如://arch/i386/kernel/irq.cstaticunsignedlongirq_affinity[NR_IRQS]={[0..
此文档下载收益归作者所有