首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

GNU C 、ANSI C、标准C、标准c++的区别和联系(2)

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
继承事业,薪火相传
返回列表