linux tricks 之 FIELD_SIZEOF.
include/linux/kernel.h
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
它通过对0指针灵活运用,是对sizeof的一种变相扩展。
2.ARRAY_SIZE获取数组维数
ARRAY_SIZE用来获取一维或者多维数组的第一维大小,并对非数组指针进行合法性检查。
include/linux/kernel.h
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
它的思想很简单,就是通过sizeof获取整个数组大大小,然后除以单个数组元素的大小。__must_be_array用来检查arr参数是否为数组指针。在gcc中它被支持,其他编译器可能将它直接定义为0:
include/linux/kernel.h
#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1) include/linux/compiler-gcc.h
#define __must_be_array(a) \
BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[])))
__builtin_types_compatible_p是gcc编译器的内嵌函数,它用于判断一个变量的类型是否为某指定的类型,假如是就返回1,否则返回0。这里通过判断指针和指针指向的第一个元素的指针是否是相同类型来判断是否为数组。BUILD_BUG_ON_ZERO的作用在于将返回值转化为编译错误信息。显然当内嵌函数返回值为0时,也即类型相同时,由于BUILD_BUG_ON_ZERO参数为非0而导致char[-1]而发出编译器警告。经过以上分析也很容易写出判断数组指针的宏,如果是返回1,否则返回0。
#define IS_ARRAY_PTR(p) (!__builtin_types_compatible_p(typeof(p), typeof(&p[0])))
无论是ARRAY_SIZE还是扩展的IS_ARRAY_PTR宏,它们只接受明确的指针参数名,而无法接受&a这样的参数,这是由于宏的扩展引起的,报错信息如下:
xxx.c:: error: subscripted value is neither array nor pointer
1.FIELD_SIZEOF获取成员大小
linux tricks 之 FIELD_SIZEOF.的更多相关文章
- linux tricks 之 BUILD_BUG_ON_ZERO.
------------------------------------------- 本文系作者原创, 欢迎大家转载! 转载请注明出处: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 ...
随机推荐
- js校验表单后提交表单的三种方法总结
第一种: 复制代码 代码如下: <script type="text/javascript"> function check(form) { if(fo ...
- virtualbox 不能为虚拟电脑打开一个新任务/VT-x features locked or unavailable in MSR.
确保了主机的BIOS中开启了Intel Virtual Technology,虚拟机配置中勾选了“启用VT-x/AMD-V”. 这是因为CPU不支持VT-X技术或者VT-X技术被锁定. 如果不打开虚拟 ...
- Eclipse启动Tomcat,45S超时问题解决
在Eclipse中启动Tomcat服务器时,经常由于系统初始化项目多,导致出现45秒超时的Tomcat服务器启动错误. 以前我一般通过找到XML配置文件,将对应Timeout为45的值,修改为 ...
- 如何看K线图基础知识
在日K线图中一般白线.黄线.紫线.绿线依次分别表示:5.10.20.60日移动平均线,但这并不是固定的,会根据设置的不同而不同,比如你也可以在系统里把它们设为5.15.30.60均线. 你看K线图的上 ...
- IE下的haslayout特性
什么是hasLayout?hasLayout是IE特有的一个属性.很多的ie下的css bug都与其息息相关.在ie中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元素来计算尺寸和组织 ...
- 建立你的第一个 Git 仓库
虽然 Git 确实是被许多重要软件选作版本控制工具,但是并不是仅能用于这些重要软件;它也能管理你购物清单(如果它们对你来说很重要的话,当然可以了!).你的配置文件.周报或日记.项目进展日志.甚至源代码 ...
- ios反射
http://www.cr173.com/html/18677_1.html 1.反射获取类属性名和属性类型 unsigned ; objc_property_t *properties = clas ...
- aspx注入靶机源码
ASPX: <%@ Page language="c#" validateRequest=false %> <!DOCTYPE HTML PUBLIC &qu ...
- C#开发实例 键盘篇
键盘的操作控制: 键盘和鼠标一样是重要输入设备的一部分.开发过程中,会涉及到很多的键盘操作控制. 2.1获取键盘信息 ①获取组合键 Windows中有很多默认的组合键,如Ctrl+v,Ctrl+A.本 ...
- 搭建自己的ngrok服务
转载:http://tonybai.com/2015/03/14/selfhost-ngrok-service/ 在国内开发微信公众号.企业号以及做前端开发的朋友想必对ngrok都不陌生吧,就目前来看 ...