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 ...
随机推荐
- FITTING A MODEL VIA CLOSED-FORM EQUATIONS VS. GRADIENT DESCENT VS STOCHASTIC GRADIENT DESCENT VS MINI-BATCH LEARNING. WHAT IS THE DIFFERENCE?
FITTING A MODEL VIA CLOSED-FORM EQUATIONS VS. GRADIENT DESCENT VS STOCHASTIC GRADIENT DESCENT VS MIN ...
- mySQL 增量备份方案(转)
1.在 /etc/my.cnf 下面设置开启bin-log 编辑 vim /etc/my.cnf [mysqld] binlog_format = MIXED ...
- 繁华模拟赛 vicent的字符串
#include<iostream> #include<cstdio> #include<string> #include<cstring> #incl ...
- Android 将可以按地点自动启动应用程序
导读Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发.尚未有统一中文名称,中国大陆地区较多人使用“安 ...
- C语言可以包含.txt文件
// fa.cpp : 定义控制台应用程序的入口点.// #include "stdafx.h"#include "iostream"#include" ...
- Linux下tomcat服务
一:Linux下tomcat服务的启动.关闭与错误跟踪,使用PuTTy远程连接到服务器以后,通常通过以下几种方式启动关闭tomcat服务:切换到tomcat主目录下的bin目录(cd usr/loca ...
- ZooKeeper 安装部署
一.解压 tar -zxvf zookeeper-3.3.5.tar.gz 二.将zookeeper-3.3.4/conf目录下面的 zoo_sample.cfg修改为zoo.cfg,配置文件内容如下 ...
- Linux运维相关目录
- BZOJ 1600
开始刷一些USACO月赛题了.. 这题简单递推就不说了. 然后我们发现暴力递推是$O(n^2)$的.看起来非常慢. 这道题拥有浓厚的数学色彩,因此我们可以从数学它的规律上找突破口. (于是暴力大法好, ...
- shell脚本步骤调试
第一种方式===> [root@localhost functions]# sh -x test.sh --check xx+ '[' --check '!=' -check ']'+ case ...