linux tricks 之 BUILD_BUG_ON_ZERO.
include/linux/kernel.h
/* Force a compilation error if condition is true */
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) /* Force a compilation error if condition is true, but also produce a
result (of value 0 and type size_t), so the expression can be used
e.g. in a structure initializer (or where-ever else comma expressions
aren't permitted). */
#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1)
注意核心表达式sizeof(char[1 - 2*!!(condition)])的作用,首先对条件表达式进行两次取反,这可以保证进行1 - 2*!!(condition)的结果只有两种值:条件为0时结果为1或者不为0则结果为-1,显然char[-1]将会导致编译器报错。注意:两次取反的目的是为了将表达式的值转换为逻辑值。
- BUILD_BUG_ON:只有条件condition为0时可编译,但不返回值,否则编译器报错。
- BUILD_BUG_ON_ZERO:只有条件e为0时返回0,否则编译器报错。
总结:BUILD_BUG_ON和BUILD_BUG_ON_ZERO作用类似,都是在参数为非0时编译报错,但是BUILD_BUG_ON_ZERO可以返回0值,BUILD_BUG_ON不可。编译器警告的格式如下,这与char[-1]的错误定义相一致。如果不熟悉它,那么将很难根据警告找到出错的真正位置:
xxx.c:: error: size of array ‘type name’ is negative
目前内核对BUILD_BUG_ON_ZERO的使用有两处:一个是在数组大小计算中用来判定指针合法行的__must_be_array宏。另一个是对模块参数进行权限检查时的__module_param_call宏。
内核对BUILD_BUG_ON的使用则要普遍的多,它被用来做编译期间的参数检查,广泛存在于内核的源码文件中。某些情况下需要一个数据结构满足特定的大小,比如jffs2文件系统中的jffs2_raw_inode结构的大小必须为68。另外可能需要为了兼容性考虑,可能需要定义一些别名,比如:
include/linux/net.h
#define SOCK_CLOEXEC O_CLOEXEC
则可以在编码时检测是否定义正确:
net/socket.c
BUILD_BUG_ON(SOCK_CLOEXEC != O_CLOEXEC);
大多数情况下,它们属于调试信息,在调试完毕后需要移除,除非它们可以指示一些特定的信息,比如第一种情况用来强调数据结构的大小为固定值。一个详细的示例如下,如果struct map结构体的大小不为32,则编译时报错。
struct map
{
int used[]; /* 8 */
int empty[]; /* 20 */ char pad[ - ];
} men = {{, }, {, , , , }}; int main()
{
BUILD_BUG_ON(sizeof(men) != );
printf("BUILD_BUG_ON_ZERO(0):%d, %d\n", BUILD_BUG_ON_ZERO(), sizeof(men)); return ;
}
linux tricks 之 BUILD_BUG_ON_ZERO.的更多相关文章
- linux tricks 之 FIELD_SIZEOF.
------------------------------------------- 本文系作者原创, 欢迎大家转载! 转载请注明出处:netwalker.blog.chinaunix.net -- ...
- linux tricks 之 container_of.
转载:http://blog.chinaunix.net/uid-20608849-id-3027972.html 由于内核中定义了很多复杂的数据结构,而它们的实例中的成员在作为函数参数传递的时,函数 ...
- linux tricks 之 bitmap分析.
------------------------------------------- 本文系作者原创, 欢迎大家转载! 转载请注明出处:netwalker.blog.chinaunix.net -- ...
- linux tricks 之数据对齐。
转载:http://blog.chinaunix.net/uid-20608849-id-3027953.html 内核为了保持最大的兼容性和代码灵活性,不可能直接对某个数据类型定义它的大小范围. ...
- linux tricks 之VA系列函数.
VA函数(variable argument function),参数个数可变函数,又称可变参数函数.C/C++编程中,系统提供给编程人员的va函数很少.*printf()/*scanf()系列函数, ...
- linux tricks 之 typeof用法.
typeof是gcc的扩展功能,比较简单,是用来取得参数类型,具体可参考gcc官网的解释. https://gcc.gnu.org/onlinedocs/gcc/Typeof.html ------- ...
- linux tricks 之 ALIGN解析.
------------------------------------------- 本文系作者原创, 欢迎大家转载! 转载请注明出处:netwalker.blog.chinaunix.net -- ...
- Linux tricks
Environment Settings Path Globally set path is in /etc/profile; or the user's .bash_profile for part ...
- linux tricks 之 roundup.
转载:http://stackoverflow.com/questions/1010922/question-about-round-up-macro 以下内容转载自stackoverflow关于 r ...
随机推荐
- block中防止循环引用的一个高大上的宏定义
看惯了什么tempSelf weakSelf,来点高大的 #define weakify(...) \ rac_keywordify \ metamacro_foreach_cxt(rac_weaki ...
- jquery uploadify 使用
/*进度条框*/ .shangchuantishikuang { border: 7px solid #74A5BF; background-color: white; font-size: 14px ...
- IHttpModule在webconfig中的注册
在asp.net中,提供了两种方式用来解决获取由asp.net服务器创建和维护的HttpApplication对象,方便注册HttpApplication对象的事件处理.这两种方式为:IHtpModu ...
- 如何快速读懂大型C++程序代码
要搞清楚别人的代码,首先,你要了解代码涉及的领域知识,这是最重要的,不懂领域知识,只看代码本身,不可能搞的明白.其次,你得找各种文档:需求文档(要做什么),设计文档(怎么做的),先搞清楚你即将要阅读是 ...
- 【一个iOS官方文档错误】关于keyWindow是否可以接受触摸事件?
[一个iOS文档错误]关于keyWindow是否可以接受触摸事件? 关于keyWindow,官方文档有一个解释: 同一时间只有一个window可以成为keyWindow,keyWindow可以接受 ...
- 第8章 Iptables与Firewalld防火墙
章节简述: 红帽RHEL7系统已经用firewalld服务替代了iptables服务,新的防火墙管理命令firewall-cmd与图形化工具firewall-config. 本章节基于数十个防火墙需求 ...
- MySQL数据库InnoDB引擎下服务器断电数据恢复
说明: 线上的一台MySQL数据库服务器突然断电,造成系统故障无法启动,重新安装系统后,找到之前的MySQL数据库文件夹. 问题: 通过复制文件的方式对之前的MySQL数据库进行恢复,发现在程序调用时 ...
- 数据库多张表导出到excel
数据库多张表导出到excel public static void export() throws Exception{ //声明需要导出的数据库 String dbName = "hdcl ...
- PHP读取csv文件
<?php //取数据 $f_d = file_get_contents('tpl_import_info.csv'); $f_d = iconv('gbk', 'utf-8', $f_d); ...
- calico for kubernetes
(这一篇中很多错误,勿参考!) The reference urls: https://github.com/kubernetes/kubernetes/blob/master/docs/gettin ...