• 读懂_countof,可以懂得什么


    在c++开发中数组是我们经常使用存储结构,而于此同时“数组越界”是每个c++程序员不能不提防陷阱。

    还好,我们有预定义宏_countof。

    一.在visual c++开发环境下,它的定义如下:

    #if !defined(_countof)

    #if !defined(__cplusplus)

    #define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))

    #else

    extern "C++"

    {

    template <typename _CountofType, size_t _SizeOfArray>

    char (*__countof_helper(UNALIGNED _CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];

    #define _countof(_Array) sizeof(*__countof_helper(_Array))

    }

    #endif

    #endif

    能引发兴趣的显然是__countof_helper,我们抽茧剥丝的看一下。

    template <typename _CountofType, size_t _SizeOfArray>

    char (*__countof_helper(UNALIGNED _CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];

    1. 它是一个函数模板的声明,并没有函数体;

    2. 它有一个参数,类型为_CountofType(&)[_SizeOfArray]的数组引用;

    3. 它的返回值是一个指向数组的指针,类型为 char (*)[_SizeOfArray];

    这里有几个知识点需要注意一下。

    1. 数组引用

    2. 数组指针

    3. 模板函数

    4. 数组指针的解引用

    理解了函数模板__countof_helper,我们再来看看宏_countof.

    #define _countof(_Array) sizeof(*__countof_helper(_Array))

    可以看到,它本质是对函数__countof_helper的返回值进行了解引用之后的sizeof

    而返回值是指向数组的指针,解引用之后自然就是数组本身了。

    对一个char类型的数组求大小,也就是数组的大小(元素个数)了。

    二.在Linux 内核中,有一个类似的求数组大小的宏ARRAY_SIZE

    它的定义为:

    #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))

    其中__must_be_array被定义为

    /* &a[0] degrades to a pointer: a different type from an array */

    #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))

    __same_type()又被定义为

    #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))

    BUILD_BUG_ON_ZERO是编译时期的断言宏,检查表达式e是否为0,为0编译通过且返回0;如果不为0,则编译不通过。

    __builtin_types_compatible_p用来判断type1和type2是否是相同的数据类型,相同返回1,否则返回0。

    一个小小的宏,有这么多东西,是不是感觉赚到了 :)

    Ref:

    http://www.cnblogs.com/liuzhanshan/p/6861596.html

    http://www.cnblogs.com/hazir/p/static_assert_macro.html

    https://msdn.microsoft.com/en-us/library/b0084kay(v=vs.100).aspx

    https://stackoverflow.com/questions/8018843/macro-definition-array-size/8021113#8021113

  • 相关阅读:
    继承和多态
    访问限制
    返回函数
    类和实例
    requests
    函数的参数
    代码块的快速放置
    19进阶、基于TSP的直流电机控制设计
    18进阶、TLC语言
    17高级、Simulink代码生成技术详解
  • 原文地址:https://www.cnblogs.com/envoy/p/8352467.html
Copyright © 2020-2023  润新知