zoukankan      html  css  js  c++  java
  • linux tricks 之 FIELD_SIZEOF.

    -------------------------------------------
    本文系作者原创, 欢迎大家转载!
    转载请注明出处:netwalker.blog.chinaunix.net
    -------------------------------------------
    1.FIELD_SIZEOF获取成员大小
     
    FIELD_SIZEOF用来获取成员大小。它需要两个参数,第一个指定结构体的类型,第二个则指明成员的名字。
     
    1 include/linux/kernel.h
    2 #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))

    它通过对0指针灵活运用,是对sizeof的一种变相扩展。

    2.ARRAY_SIZE获取数组维数

    ARRAY_SIZE用来获取一维或者多维数组的第一维大小,并对非数组指针进行合法性检查。

     

    1 include/linux/kernel.h
    2 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))

     

    它的思想很简单,就是通过sizeof获取整个数组大大小,然后除以单个数组元素的大小。__must_be_array用来检查arr参数是否为数组指针。在gcc中它被支持,其他编译器可能将它直接定义为0:

    1 include/linux/kernel.h
    2 #define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1)
    3 
    4 include/linux/compiler-gcc.h
    5 #define __must_be_array(a) 
    6   BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0])))

    __builtin_types_compatible_p是gcc编译器的内嵌函数,它用于判断一个变量的类型是否为某指定的类型,假如是就返回1,否则返回0。这里通过判断指针和指针指向的第一个元素的指针是否是相同类型来判断是否为数组。BUILD_BUG_ON_ZERO的作用在于将返回值转化为编译错误信息。显然当内嵌函数返回值为0时,也即类型相同时,由于BUILD_BUG_ON_ZERO参数为非0而导致char[-1]而发出编译器警告。经过以上分析也很容易写出判断数组指针的宏,如果是返回1,否则返回0。

    1 #define IS_ARRAY_PTR(p)    (!__builtin_types_compatible_p(typeof(p), typeof(&p[0])))

    无论是ARRAY_SIZE还是扩展的IS_ARRAY_PTR宏,它们只接受明确的指针参数名,而无法接受&a这样的参数,这是由于宏的扩展引起的,报错信息如下:

    1 xxx.c:17: error: subscripted value is neither array nor pointer

    1.FIELD_SIZEOF获取成员大小

  • 相关阅读:
    Windows SDK编程(Delphi版) 之 应用基础,楔子
    一个小问题引发的论证思考
    Delphi 组件开发教程指南(7)继续模拟动画显示控件
    用PyInstaller将python转成可执行文件exe笔记
    使用 .Net Memory Profiler 诊断 .NET 应用内存泄漏(方法与实践)
    Microsof Office SharePoint 2007 工作流开发环境搭建
    How to monitor Web server performance by using counter logs in System Monitor in IIS
    LINQ之Order By
    window 性能监视器
    内存泄露检测工具
  • 原文地址:https://www.cnblogs.com/3me-linux/p/6210483.html
Copyright © 2011-2022 走看看