Linux 内核使用的 GNU C 扩展

本文介绍了Linux内核广泛使用的GNU C扩展,包括语句表达式、typeof、零长度数组、可变参数宏、标号元素、case范围、声明的特殊属性等。这些扩展提供了更强大的功能和优化,例如通过typeof实现类型安全的宏,使用零长度数组简化变长对象头结构,以及通过声明属性进行手动优化和更严格的代码检查。文章还探讨了内建函数,如__builtin_return_address和__builtin_expect,它们帮助编译器进行优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

===========================

Linux 内核使用的 GNU C 扩展

===========================


GNC CC 是一个功能非常强大的跨平台 C 编译器,它对 C 语言提供了很多扩展,
这些扩展对优化、目标代码布局、更安全的检查等方面提供了很强的支持。本文把
支持 GNU 扩展的 C 语言称为 GNU C。



Linux 内核代码使用了大量的 GNU C 扩展,以至于能够编译 Linux 内核的唯一编
译器是 GNU CC,以前甚至出现过编译 Linux 内核要使用特殊的 GNU CC 版本的情
况。本文是对 Linux 内核使用的 GNU C 扩展的一个汇总,希望当你读内核源码遇
到不理解的语法和语义时,能从本文找到一个初步的解答,更详细的信息可以查看
gcc.info。文中的例子取自 Linux 2.4.18。


语句表达式

==========

GNU C 把包含在括号中的复合语句看做是一个表达式,称为语句表达式,它可以出
现在任何允许表达式的地方,你可以在语句表达式中使用循环、局部变量等,原本
只能在复合语句中使用。例如:

++++ include/linux/kernel.h

159: #define min_t(type,x,y)
160:         ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
++++ net/ipv4/tcp_output.c
654:         int full_space = min_t(int, tp->window_clamp, tcp_full_space(sk));

复合语句的最后一个语句应该是一个表达式,它的值将成为这个语句表达式的值。
这里定义了一个安全的求最小值的宏,在标准 C 中,通常定义为:


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

这个定义计算 x 和 y 分别两次,当参数有副作用时,将产生不正确的结果,使用
语句表达式只计算参数一次,避免了可能的错误。语句表达式通常用于宏定义。

Typeof

======


使用前一节定义的宏需要知道参数的类型,利用 typeof 可以定义更通用的宏,不
必事先知道参数的类型,例如:

++++ include/linux/kernel.h

141: #define min(x,y) ({
142:         const typeof(x) _x = (x);      
143:         const typeof(y) _y = (y);      
144:         (void) (&_x == &_y);           
145:         _x < _y ? _x : _y; })

这里 typeof(x) 表示 x 的值类型,第 142 行定义了一个与 x 类型相同的局部变
量 _x 并初使化为 x,注意第 144 行的作用是检查参数 x 和 y 的类型是否相同。
typeof 可以用在任何类型可以使用的地方,通常用于宏定义。


零长度数组

==========

GNU C 允许使用零长度数组,在定义变长对象的头结构时,这个特性非常有用。例
如:



++&#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值