Linux内核学习(1)-常用GNUC技巧

常用GNU C技巧

GNU C对ANSI C进行了扩展,所以GCC有一些扩展的新特性

(1)语句表达式

括号里的复合语句可以看作一个表达式,并可以使用循环和局部变量等。通常用在宏定义中,可以让宏定义更加安全。

#define max(a,b) \
({int _a = (a), _b = (b); _a > _b ? _a : _b;})

(2) typeof

可用来获取类型来构造新的类型

typeof (*x) y;  //声明y是x指针指向的类型

(3)零长数组

允许使用变长数组

<mm/percpu.c>
struct pcpu_chunk{
	struct list_head list;
	unsigned long 	 populated[]; /*变长数组*/
}

populated被定义为0长度数组,不占结构体空间。

(4)case 范围

case支持范围作为标签

case low ... high:
case 'A' ... 'Z':
case 1 ... 3:

"…"两边有空格。

(5) 标号元素

  • 在标准C里,数组或者结构变量的初始化值必须以固定的顺序出现,而在GCC中,通过制定索引或者结构域名,则允许初始化值以任意顺序出现。
    对于结构体初始化,比如:
struct  person  Bill = {
                  .name = “Bill Gates”;
                  .age = 50;
                  .wealth’s world ranking = 1;
};

(6)可变参数宏

宏可以接收可变数目的参数,主要运用再输出函数里

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

使用“##”是为了处理 arg 不代表任何参数的情况,这时候,前面的逗号就变得多余了。

(7)函数属性

  • GNU C 允许声明函数、变量和类型的特殊属性,以便手动优化代码和定制代码检查的方法。
  • 格式为__attribute__((attribute_list))

(8)内建函数

  • GNU C 提供了大量内建函数,其中大部分是标准 C 库函数的 GNU C 编译器内建版本,以“builtin”作为函数名前缀。

(9)asmlinkage

  • 对于x86结构,函数参数和局部变量被一起分配到函数的局部堆栈中
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))

attribute((regparm(0))):告诉编译器该函数不需要通过任何寄存器来传递参数,只通过堆栈来传递。

(10)UL

UL强制把int类型定义为unsigned long类型,防止溢出
1UL表示无符号长整形数字1.

你可能感兴趣的:(Linux内核)