-------------------------------------------
本文系作者原创, 欢迎大家转载!
转载请注明出处: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. hdu 5747 Aaronson

    T :  1 n m:  10  2 题解:20 * 0  +  21* 1  +  22* 2 = 10 输出:3  <--  0+1+2=3 AC 代码: #include<stdio ...

  2. 只能输入汉字js脚本

    <html> <head> <meta http-equiv="Content-Type" content="text/html" ...

  3. C# 三种实现抖屏的方式

    //int a = -2; //this.BringToFront(); //for (int i = 0; i < 20; i++) //{ // a = -a; // this.Locati ...

  4. Java-Java中System.arraycopy() 和 Arrays.copyOf()两者之间的区别

    如果我们想拷贝一个数组,我们可能会使用System.arraycopy()或者Arrays.copyof()两种方式.在这里,我们将使用一个比较简单的示例来阐述两者之间的区别. 1.示例代码: Sys ...

  5. apue第六章学习总结

    apue第六章学习总结 1.关于阴影文件与口令 在口令文件当中,常见的字段有(以root为例): root(用户名):x(加密口令):0(uid):0(gid):root(注释字段):/root(用户 ...

  6. loadrunner跑场景的时候出现:Abnormal termination, caused by mdrv process termination

    1.问题 loadrunner跑场景的时候出现:Abnormal termination, caused by mdrv process termination. 备注:我使用的是RTE协议录制的脚本 ...

  7. Android第三方jar包ClassNotFind

    转载请注明http://www.cnblogs.com/vanezkw/archive/2012/06/25/2561393.html 相信很多朋友在使用第三方包时都遇到过此类问题.今天就此问题进行一 ...

  8. [Effective JavaScript 笔记] 第9条:始终声明局部变量

    如果忘记将变量声明为局部变量,该变量将会隐式地转变为全局变量 function swap(a,i,j){ temp=a[i]; a[i]=a[j]; a[j]=temp; } 尽管该程序没有使用var ...

  9. UIView 注意问题

    1. UIView.userInteractionEnabled UIView.userInteractionEnabled默认值是YES http://blog.csdn.net/studyreco ...

  10. Java正则表达式的最简单应用

    String emailRegex = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"; Pattern pat = ...