• 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获取成员大小

  • 相关阅读:
    基于 HTML5 + WebGL 实现的垃圾分类系统
    B/S 端基于 HTML5 + WebGL 的 VR 3D 机房数据中心可视化
    基于 Web 端 3D 地铁站可视化系统
    HTML5 + WebGL 实现的垃圾分类系统
    基于HTML5 WebGL的工业化3D电子围栏
    iOS 不支持 PWA,那又怎么样?
    PWA 入门: 写个非常简单的 PWA 页面
    iOS UTI
    canOpenURL: failed for URL: "weixin://app/wx 问题解决方式
    iOS扩大UIButton按钮的可点击区域
  • 原文地址:https://www.cnblogs.com/3me-linux/p/6210483.html
Copyright © 2020-2023  润新知