GNU C和标准C的区别( 二 )

将结构 ext2_file_operations 的元素 llseek 初始化为 generic_file_llseek , 元素 read 初始化为 genenric_file_read , 依次类推 。我觉得这是 GNU C 扩展中最好的特性之一 , 当结构的定义变化以至元素的偏移改变时 , 这种初始化方法仍然保证已知元素的正确性 。对于未出现在初始化中的元素 , 其初值为 0 。
7、当前函数名
GNU CC 预定义了两个标志符保存当前函数的名字 , __FUNCTION__ 保存函数在源码中的名字 , __PRETTY_FUNCTION__ 保存带语言特色的名字 。在 C 函数中 , 这两个名字是相同的 , 在 C++ 函数中 , __PRETTY_FUNCTION__ 包括函数返回类型等额外信息 , linux 内核只使用了 __FUNCTION__ 。
void example(){  printf{“This is function:%s”, __FUNCTION__};}代码中__FUNCTION__意味着字符串“example” 。
8、特殊属性声明
GNU C 允许声明函数、变量和类型的特殊属性 , 以便手工的代码优化和更仔细的代码检查 。要指定一个声明的属性 , 在声明后写 __attribute__ (( ATTRIBUTE ))其中 ATTRIBUTE 是属性说明 , 多个属性以逗号分隔 。GNU C 支持十几个属性 , 这里介绍最常用的:
noreturn
属性 noreturn 用于函数 , 表示该函数从不返回 。这可以让编译器生成稍微优化的代码 , 最重要的是可以消除不必要的警告信息比如未初使化的变量 。例如:
# define ATTRIB_NORET   __attribute__((noreturn)).... asmlinkage NORET_TYPE void do_exit(long error_code) ATTRIB_NORET;format
属性 format 用于函数 , 表示该函数使用 printf, scanf 或 strftime 风格的参数 , 使用这类函数最容易犯的错误是格式串与参数不匹配 , 指定 format 属性可以让编译器根据格式串检查参数类型 。例如:
asmlinkage int printk(const char * fmt, ...)    __attribute__ ((format (printf, 1, 2)));表示第一个参数是格式串 , 从第二个参数起根据格式串检查参数 。
unused
属性 unused 用于函数和变量 , 表示该函数或变量可能不使用 , 这个属性可以避免编译器产生警告信息 。
aligned
属性 aligned 用于变量、结构或联合类型 , 指定变量、结构域、结构或联合的对齐量 , 以字节为单位 , 例如:
struct example_struct{ char a; int   b; long c;} __attribute__((aligned(4)));表示该结构类型的变量以4字节对界 。
packed
属性 packed 用于变量和类型 , 用于变量或结构域时表示使用最小可能的对齐 , 用 于枚举、结构或联合类型时表示该类型使用最小的内存 。例如:
struct example_struct{char a;int b__attribute__ ((packed));long c__attribute__((packed));};对于结构体example_struct而言 , 在i386平台下 , 其sizeof的结果为9 , 如果删除其中的2个—attribute__((packed)),其sizeof将为12.
9、内建函数
GNU C 提供了大量的内建函数 , 其中很多是标准 C 库函数的内建版本 , 例如memcpy , 它们与对应的 C 库函数功能相同 , 不属于库函数的其他内建函数的名字通常以 __builtin 开始 。例如:
【GNU C和标准C的区别】
__builtin_return_address (LEVEL)
内建函数 __builtin_return_address 返回当前函数或其调用者的返回地址 , 参数 LEVEL 指定在栈上搜索框架的个数 , 0 表示当前函数的返回地址 , 1 表示当前函数的调用者的返回地址 , 依此类推 。
__builtin_constant_p(EXP)
内建函数 __builtin_constant_p 用于判断一个值是否为编译时常数 , 如果参数EXP 的值是常数 , 函数返回 1 , 否则返回 0 。
__builtin_expect(EXP, C)
内建函数 __builtin_expect 用于为编译器提供分支预测信息 , 其返回值是整数表
达式 EXP 的值 , C 的值必须是编译时常数 。
例如 , 下面的代码检测第一个参数是否为编译时常数以确定采用参数版本还是非参数版本代码:
#define test_bit(nr,addr)(__builtin_constant_p(nr) ?constant_test_bit((nr),(addr)) :   variable_test_bit((nr),(addr)))



推荐阅读