GNU C 9条扩展语法【linux 设备驱动开发详解】

 

GNU C 对标准C进行一系列扩展,以增强标准C的功能。

1、零长度和变量长度数组

    GNU C 允许使用零长度数组,比如 char data[0];

    GNU C 允许使用一个变量定义数组的长度如:

        int n=0;

        scanf("%d",&n);

        int array[n];

2、case 范围

    GNU C支持 case x...y这样的语法,[x,y]之间数均满足条件。

        case 'a'...'z':  /*from 'a' to 'z'*/

        break

3、语句表达式

    GNU C 把包含在括号中的复合语句看作是一个表达式,称为语句表达式。

        #define min_t(type,x,y)\

                ({type __x=(x); type __y=(y);__x<__y?__x:__y;})

        这种写法可以避免

        #define min_t(x,y) ((x)<(y)?(x):(y))

        在min_t(x++,++y)中出现的副作用

4、typeof 关键字

    typeof(x)可以获得x的类型借助typeof关键字我们可以重新定义min_t:

    #define min_t(x,y)\

            ({typeof(x) __x=(x); typeof(y) __y=(y);__x<__y?__x:__y;})

5、可变参数宏

    GNU C中宏也支持可变参数

        #define pr_debug(fmt,arg...) \

                printk(fmt,##arg)

        这里使用##的原因是处理arg不代表任何参数的情况,这时候,前面的逗号就变得多余使用##之后GNU C编译器会丢弃前面的逗号。

6、标号元素

        标准C要求数组或结构体的初始化值必须以固定的顺序出现,在GNU C中,通过指定索引或结构体成员名,允许初始化以任意顺序出现。

                unsigned char data[MAX] ={

                     [0]=10,

                      [10]=100,

                 };

             struct file_operations ext2_file_operations={

                    open:ext2_open,

                    close:ext2_close,

              };

      在linux 2.6中推荐如下方式

              struct file_operations ext2_file_operations={

                 .read=ext2_read,

                 .write=ext2_write,

               };

7、当前函数名

            GNU C中预定义两个标志符保存当前函数的名字,__FUNCTION__保存函数在源码中的名字, __PRETTY__FUNCTION__保存带语言特色的名字。在C函数中这两个名字是相同的.

          void func_example()

           {

               printf("the function name is %s",__FUNCTION__);

          }

      在C99中支持__func__宏,因此建议使用__func__替代__FUNCTION__

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;

       struct example_struct{

          char a;

          int b;

          long c;

     } __attribute__((aligned(4)));

     上述表示结构体以四个字节对齐

        struct example_struct{

                 char a;

                 int b;

                 long c;

              } __attribute__((packed));

   9、内建函数

          GNU C提供了大量的内建函数,例如memcpy,不属于库函数的其他内建函数的命名通常以__buildin开始,如下所示。

          内建函数__builtin_return_address(LEVEL)返回当前函数或其调用者的返回地址,参数LEVEL指定调用栈的级数,如0表示当前函数的返回地址,1表示当前函数调用者的返回地址。

        内建函数__builtin_constant_p(EXP,C)用于为编译器提供分支预测信息,其返回值是整数表达式EXP的值,C的值必须是编译常数。

        示例代码:

          #define test_bit(nr,addr)  \

          (__builtin_constant_p(nr))? \

         constant_test_bit((nr),(addr)):\

         variable_test_bit((nr),(addr))

 

若不想使用GNU C扩展,那么只需要在gcc参数后面加上 -ansi -pedantic即可,使用上述参数后,所有GNC C扩展语法部分将会有编译警报。

你可能感兴趣的:(linux内核及驱动学习)