China Open source community
站内导航:

 
 
 
当前位置: 首页 >> 程序设计 >> Linux 内核使用的 GNU GCC 的C 扩展
 

Linux 内核使用的 GNU GCC 的C 扩展

作者:      来源:linuxforum.net     发表时间:2006-03-16     浏览次数:      字号:    



齐量,以字节为单位,例如:



++++ include/asm-i386/processor.h

294: struct i387_fxsave_struct {

295:         unsigned short  cwd;

296:         unsigned short  swd;

297:         unsigned short  twd;

298:         unsigned short  fop;

299:         long    fip;

300:         long    fcs;

301:         long    foo;

......

308: } __attribute__ ((aligned (16)));



表示该结构类型的变量以 16 字节对齐。通常编译器会选择合适的对齐量,显示指

定对齐通常是由于体系限制、优化等原因。



* packed



属性 packed 用于变量和类型,用于变量或结构域时表示使用最小可能的对齐,用

于枚举、结构或联合类型时表示该类型使用最小的内存。例如:



++++ include/asm-i386/desc.h

51: struct Xgt_desc_struct {

52:         unsigned short size;

53:         unsigned long address __attribute__((packed));

54: };



域 address 将紧接着 size 分配。属性 packed 的用途大多是定义硬件相关的结

构,使元素之间没有因对齐而造成的空洞。





当前函数名

==========



GNU CC 预定义了两个标志符保存当前函数的名字,__FUNCTION__ 保存函数在源码

中的名字,__PRETTY_FUNCTION__ 保存带语言特色的名字。在 C 函数中,这两个

名字是相同的,在 C++ 函数中,__PRETTY_FUNCTION__ 包括函数返回类型等额外

信息,Linux 内核只使用了 __FUNCTION__。



++++ fs/ext2/super.c

98: void ext2_update_dynamic_rev(struct super_block *sb)

99: {

100:         struct ext2_super_block *es = EXT2_SB(sb)->s_es;

101:

102:         if (le32_to_cpu(es->s_rev_level) > EXT2_GOOD_OLD_REV)

103:                 return;

104:

105:         ext2_warning(sb, __FUNCTION__,

106:                      "updating to rev %d because of new feature flag, "

107:                      "running e2fsck is recommended",

108:                      EXT2_DYNAMIC_REV);



这里 __FUNCTION__ 将被替换为字符串 "ext2_update_dynamic_rev"。虽然

__FUNCTION__ 看起来类似于标准 C 中的 __FILE__,但实际上 __FUNCTION__

是被编译器替换的,不象 __FILE__ 被预处理器替换。





内建函数

========



GNU C 提供了大量的内建函数,其中很多是标准 C 库函数的内建版本,例如

memcpy,它们与对应的 C 库函数功能相同,本文不讨论这类函数,其他内建函数

的名字通常以 __builtin 开始。



* __builtin_return_address (LEVEL)



内建函数 __builtin_return_address 返回当前函数或其调用者的返回地址,参数

LEVEL 指定在栈上搜索框架的个数,0 表示当前函数的返回地址,1 表示当前函数

的调用者的返回地址,依此类推。例如:



++++ kernel/sched.c

437:                 printk(KERN_ERR "schedule_timeout: wrong timeout "

438:                        "value %lx from %pn", timeout,

439:                        __builtin_return_address(0));



* __builtin_constant_p(EXP)



内建函数 __builtin_constant_p 用于判断一个值是否为编译时常数,如果参数

EXP 的值是常数,函数返回 1,否则返回 0。例如:



++++ include/asm-i386/bitops.h

249: #define test_bit(nr,addr)

250: (__builtin_constant_p(nr) ?

251:  constant_test_bit((nr),(addr)) :

252:  variable_test_bit((nr),(addr)))



很多计算或操作在参数为常数时有更优化的实现,在 GNU C 中用上面的方法可以

根据参数是否为常数,只编译常数版本或非常数版本,这样既不失通用性,又能在

参数是常数时编译出最优化的代码。



* __builtin_expect(EXP, C)



内建函数 __builtin_expect 用于为编译器提供分支预测信息,其返回值是整数表

达式 EXP 的值,C 的值必须是编译时常数。例如:



++++ include/linux/compiler.h

13: #define likely(x)       __builtin_expect((x),1)

14: #define unlikely(x)     __builtin_expect((x),0)

++++ kernel/sched.c

564:         if (unlikely(in_interrupt())) {

565:                 printk("Scheduling in interruptn");

566:                 BUG();

567:         }



这个内建函数的语义是 EXP 的预期值是 C,编译器可以根据这个信息适当地重排

语句块的顺序,使程序在预期的情况下有更高的执行效率。上面的例子表示处于中

断上下文是很少发生的,第 565-566 行的目标码可能会放在较远的位置,以保证

经常执行的目标码更紧凑。
[next]

gcc扩展(extension) GCCe

1.表达式的陈述和申明。



   数据安全性

   in Standard C:

      #define max(a,b) ((a)>(b)?(a):(b))

   in Gcc:  ( assume type is int )

      #define maxint(a,b)

              ({int _a=(a), _b=(b),;

                  _a>_b?_a:_b;})



2.本地申明标签(locally declared labels)

   in Gcc:

      __label__  name ;



3.可附值得标签

   " && " 运算符--返回标签地址

   in Gcc:

      void * ptr;

      ptr = &&foo;

      goto *ptr;

     

      static void *array[] = { &&foo, &&bar, &&hack };

      goto *array;



      static const int array[] = { &&foo - &&foo, &&bar -
&&foo, &&hack - &&foo };

      goto * (&&foo+ array);



4.陷套函数(nested function)





5.构建函数调用(contructing function call)

  in Gcc:

     void * __builtin_apply_args()

     返回一个由参数指针寄存器,结构值地址(structure value
address),全部寄存器组成的堆栈的地址

     void * __builtin_apply( void (*function)(), void * arguments, size_t size)

     用 *arguments和size指定的参数调用 (*function).

     void * __builtin_return( void * result)

     返回result从包含的函数



6.给表达式取名字(naming an expression`s type)

    typedef



7.用typeof()递交类型

    如果是在 *.h 文件里,则用 __typeof__



8.推广的左附值

  in Gcc:

     (a , b) += 5

     a, (b +=5 )



     &(a,b)

     a, &b



     ( a ? b : c ) = 5

     ( a ? b = 5 : ( c = 5 ))

   

     (int)a = 5

     (int) ( a = (char *)(int) 5 )



     (int)a += 5

     (int) ( a = (char *)((int)a + 5))

       

     *&(int)f = 1



9.条件省略

  in Gcc:

     x ? : y       EQU      x ? x : y



10.双字整形数

  in Gcc:

     long long

     unsigned long long

     LL

     ULL



11.复杂数

   in Gcc:

      _Complex

      __complex__

      __imag__



12.16位浮点数

   in Gcc:

      0x0.f is (15/16)

      p3    is  multiplies by 8

      so

      0x0.fp3 is 1.55e1



13.长度为0的矩阵(arrays of length zero)



14.可变长度矩阵(arrays of variable length)

   in Gcc:

      struct entry

      tester (int len, char data[len][len]){



       }



15.可变量参数的宏( macros with variable number of arguments)

   in Gcc:

      #define debug(format, ...) fprintf(stderr, format, __VA_ARGS__)

      "..."是一个可变参数



16.slightly looser rules for escaped newlines



17.string literals with embedded newlines



18.non-lvalue arrays may have subscripts

   in Gcc:

   struct foo{ int a[4]};

   struct foo f();

   bar (int index){

       return f().a[index];

   }



19.void- 和 function-pointers 的转换( arithmetic on void- and function-pointer)

   arg with gcc:

       -Wpointer-arith  -- to warning if the arithmetic are used



20.非常数初始化( non-constant initializers )

   in Gcc:

      foo(float f, float g){

         float beat_freqs[2] = { f-g, f+g };

      }



21.字面上的组合( compound literals )



22.指明的初始化( designated initializers )

   in Gcc:

      int a[6] = { [4] = 29, [2] = 15};

      int withs[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3};



23. case ranges



24. cast to a union type

                

25. mixed devlarations and code



26. declaring attributes of functions

    in Gcc:

    __attribute__

    total 14 attributes: noreturn, pure, const, format, format_arg,
no_instrument_function, section, constructor, destructor, unused, weak, malloc, alias,
no_check_memory_usage,regparm(number),stdcall,cdecl,longcall,short_call....





27.属性语法(attribute syntax)

本节描述__attribute__可能用到的语法,和在C中属性特殊绑定的构造,一些细节会多样的对C++?br>蚾bjective C.因为属性文法的不幸,一些在这里描述的格式不能被全部成功地分析。

  see 5.26 [function attributes]

      5.33 [variable attributes]

      5.34 [type attributes]

一个属性指示是格式__attribute__((attribute-list))

一个属性列表可能是一个空的逗号隔开的属性序列,每一个属性是下列中的一个:

  1.空

  2.字

  ......

一个属性指示表(attribute specifier list)是一个或多个属性指示,不被任何记号分离

一个属性指示可以出现在标号的冒号后面,除了 case , default

但是它是不用的(unused),但是要用'-Wall'编译



一个属性指示可以是struct, union, enum 指示的一部分,如果struct,union,enum为空则忽略它



另外,一个属性指示可以是一个申明,未名命的计数申明和类型名的一部分



以后,一个属性指示在很多地方作为一个特殊申明符代替了,一些例子在下面



当一个属性指示申明为函数或矩阵的参数,他会付给函数隐含的盖住参数的指针,但是这个现在还没
有真确的实现



任何指示的列表在??????? p172.s4



一个属性指示列表能出现在一个声明前面,而且对他后面的申明都有效

__attribute((noreturn)) void d0(void), __attribute__((format(printf,1,2))) d1(const
char *, ...), d2(void)

其中'noreturn'对全部申明,'format'只能为d1声明,如果为d2声明则产生错误



一个属性指示列表能出现在逗号(,),等号("),分号(")



(****f)(void)
__attribute__((noreturn)),现在'noreturn'属性申明到f,导致警告f不是一个函数,但是以后将
能申明到这个函数 ****f



???

???

???  p173



28.原形和经典风格的函数定义



29.C++风格的注释



30.带美金符号的名字



31.'ESC'常数

ascii ESC = 'e'



32.追根究底的变量和类型对齐

   __alignof__(foo)

   exp:

   __alignof__(double) is 8 on may RISC

   __alignof__(double) is 4 or even 2 on more tradidional machine



33.变量的属性

   8 attributes:

     aligned, mode, nocommon, packed, section, transparent_union, unused, weak,
share(only in WinNT)

    

    NOTE:

     mode(mode): byte, __byte__, word, __word__, pointer, __pointer__

 

     nocommon:
用'-fno-common'编译,将会将全部的变量编译为nocommon,直接分配空间给它,并全部置为0,一个?br>淞恐荒茉谝桓鲈次募

[1] [2] [3]

编辑 webmaster

 
 
 
评论
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •  
    中国源码网 - WWW.YUANMA.ORG - 中国开放源代码社区