GNU C 、ANSI C、标准C、标准c++的区别和联系(2)
- UID
- 1029342
- 性别
- 男
|
GNU C 、ANSI C、标准C、标准c++的区别和联系(2)
5、可变参数的宏
标准C只支持可变参数的函数,意味着函数的参数可以是不固定的
例如printf()函数的原型是
int printf(const char *format [,argument]...)
而在GNU C中,宏也可以接受可变数目的参数,例如
#define pr_debug(fmt,arg...) printk(fmt,##arg)
这里arg表示其余的参数可以是零个或多个,这些参数以及参数之间的逗号构成arg的值,
在宏扩展时替换arg ,例如
pr_debug("%s:%d",filename,line);
被扩展为
printk("%s:%d",filename,line);
使用##的原因是为了处理arg不代表任何参数的情况,这时候,前面的逗号就变得多余了。
使用##之后,GNU C预处理器会丢弃前面的逗号,这样代码
pr_debug("success!/n") 会被正确扩展为 printk("success!/n")
而不是 printk("success!/n",);
6.标号元素
标准c要求数组或结构体的初始化值必须以固定的顺序出现,在GNU C中,通过指定索引或结构体成员名,允许初始化值得以任意顺序出现。
指定数组索引的方法是在初始化值前添加 [INDEX]= ,当然也可以用 [FIRST...LAST]= 的形式指定一个范围。例如下面的代码定义一个数组,并把其中的所有元素赋值为0:
unsigned char data[MAX] ={[0...MAX-1]=0 };
下面的代码借助结构体成员名初始化结构体:
[cpp] view plaincopyprint?
- struct file_operations DEMO_fops = {
- owner : THIS_MODULE,
- llseek: DEMO_llseek,
- read: DEMO_read,
- write: DEMO_write,
- ioctl: DEMO_ioctl,
- open: DEMO_open,
- release: DEMO_release,
- };
但是Linux 2.6还是推荐采用标准C的方式,如下
[cpp] view plaincopyprint?
- struct file_operations DEMO_fops = {
- .owner = THIS_MODULE,
- .llseek = DEMO_llseek,
- .read = DEMO_read,
- .write = DEMO_write,
- .ioctl = DEMO_ioctl,
- .open = DEMO_open,
- .release = DEMO_release,
- };
7.当前函数名
GUN C预定义了两个标识符保存当前的函数名,__FUNCTION__保存函数在源码中的名字,
__PRETTY_FUNCTION__保存带语言特色的名字。在c函数中,这两个名字是相同的。
void example()
{
printf("This is function: %s ",__FUNCTION__);
}
代码中的__FUNCTION__意味着字符串"example"
8、特殊属性声明
GNU C允许声明函数、变量和类型的特殊属性,以便进行手工的代码优化和定制代码检查的方法。指定一个声明的属性,只需要在申明后添加 __attribute__((ATTRIBUTE))
其中ATTRIBUTE为属性说明,如果存在多个属性,则以逗号分隔。GNU C支持noreturn format section aligned packed等十多个属性
noreturn属性作用于函数,表示该函数从不返回。这会让编译器优化代码,并消除不必要的的警告信息。例如
#define ATTRIB_NORET __attribute__ ((noreturn)) ....
asmlinkage NORET_TYPE void do_exit(long error_code) ATTRIB_NORET;
format属性也可用于函数,表示该函数printf scanf 或strftime风格的参数,指定format属性可以让编译器根据格式串检查参数类型。例如:
asmlinkage int printk(const char * fmt,...)/
__attribute__((format(printf,1,2)));
详细的可以看http://blog.163.com/sunm_lin/blog/static/9192142200741533038695/
unused属性作用于函数和变量,表示该函数或变量可能不会被用到,避免编译器产生的警告信息。
aligned属性指定结构体、变量、联合体的对齐方式。packed属性作用于变量和类型,表示压缩结构体,使用最小的内存。
[cpp] view plaincopyprint?
- struct examprl_struct
- {
- char a;
- int b;
- long c;
- }__attribute__((packed));
注意,这个__attribute__((packed))只能用在GNU C
关于在VC下的结构体对齐,参照http://hi.baidu.com/deep_pro/blo ... b604debd3e1e01.html |
|
|
|
|
|