-------------------------------------------
本文系作者原创, 欢迎大家转载!
转载请注明出处:netwalker.blog.chinaunix.net
-------------------------------------------
1.FIELD_SIZEOF获取成员大小
 
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.的更多相关文章

  1. linux tricks 之 BUILD_BUG_ON_ZERO.

    ------------------------------------------- 本文系作者原创, 欢迎大家转载! 转载请注明出处:netwalker.blog.chinaunix.net -- ...

  2. linux tricks 之 container_of.

    转载:http://blog.chinaunix.net/uid-20608849-id-3027972.html 由于内核中定义了很多复杂的数据结构,而它们的实例中的成员在作为函数参数传递的时,函数 ...

  3. linux tricks 之 bitmap分析.

    ------------------------------------------- 本文系作者原创, 欢迎大家转载! 转载请注明出处:netwalker.blog.chinaunix.net -- ...

  4. linux tricks 之数据对齐。

    转载:http://blog.chinaunix.net/uid-20608849-id-3027953.html   内核为了保持最大的兼容性和代码灵活性,不可能直接对某个数据类型定义它的大小范围. ...

  5. linux tricks 之VA系列函数.

    VA函数(variable argument function),参数个数可变函数,又称可变参数函数.C/C++编程中,系统提供给编程人员的va函数很少.*printf()/*scanf()系列函数, ...

  6. linux tricks 之 typeof用法.

    typeof是gcc的扩展功能,比较简单,是用来取得参数类型,具体可参考gcc官网的解释. https://gcc.gnu.org/onlinedocs/gcc/Typeof.html ------- ...

  7. linux tricks 之 ALIGN解析.

    ------------------------------------------- 本文系作者原创, 欢迎大家转载! 转载请注明出处:netwalker.blog.chinaunix.net -- ...

  8. Linux tricks

    Environment Settings Path Globally set path is in /etc/profile; or the user's .bash_profile for part ...

  9. linux tricks 之 roundup.

    转载:http://stackoverflow.com/questions/1010922/question-about-round-up-macro 以下内容转载自stackoverflow关于 r ...

随机推荐

  1. wifi共享小工具

    MainForm.cs: using System;using System.Collections.Generic;using System.ComponentModel;using System. ...

  2. EL表达式从request和session中取值

    在Action中保存登录的基本信息:request.getSession().setAttribute("adminid", str); 在JSP页面中:${sessionScop ...

  3. U盘10分钟安装linux系统

    说来可能不信,10分钟包括创建U盘启动盘,用U盘启动,安装,不联网,不更新,不安装语言包,等装好系统再更新. Windows系统硬盘分区 如果你用的是Windows系统,现有的硬盘没有未分配的空间,需 ...

  4. JNI环境变量——JNIEnv*的使用 &&配置jd环境变量

      如果没有配置环境变量,先配置环境变量,如下: 1.右键我的电脑——高级——环境变量——下面的系统变量 2.选择[新建系统变量]--弹出“新建系统变量”对话框,在“变量名”文本框输入“JAVA_HO ...

  5. SVM算法入门

    转自:http://blog.csdn.net/yangliuy/article/details/7316496SVM入门(一)至(三)Refresh 按:之前的文章重新汇编一下,修改了一些错误和不当 ...

  6. lamp 网站打不开,不显示也不报错,

    原因是该网站的编程员,习惯简写,<? ?>;而服务器版本的php.ini 默认不支持只支持<?php ?>这种格式. 解决方法vim /usr/loacl/php/etc/ph ...

  7. Math.Round函数详解

    有不少人误将Math.Round函数当作四舍五入函数在处理, 结果往往不正确, 实际上Math.Round采用的是国际通行的是 Banker 舍入法. Banker's rounding(银行家舍入) ...

  8. Q1微信用户增长11% 微信生态圈逐渐完善

    就在今天早些时候,腾讯公布了Q1财报,微信和手Q游戏收入达18亿元,微信用户环比增长11%,微信生态圈逐渐完善.和xmyanke一起来看看具体的财报数字分析. 微信和手Q游戏付费用户环比增长100%以 ...

  9. Seventh scrum meeting - 2015/11/1

    新的一月开始了!今天是周末,所以大家的开发进度有点减慢,享受一个愉快的周末~ 今天大家的开发都没有遇到什么问题,因为这几天下来,大家对android的开发流程都比较熟悉了,暂时不会遇到新的问题了. 我 ...

  10. 记录:js删除数组中某一项或几项的几种方法

    1:js中的splice方法 splice(index,len,[item])    注释:该方法会改变原始数组. splice有3个参数,它也可以用来替换/删除/添加数组内某一个或者几个值 inde ...