在include/linux/kernel.h中有一个定义:

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

这个宏定义用于取得一个数组中元素的个数,与一般定义不同的是,这个定义加上了+ __must_be_array(arr)这个尾巴,这个定义同时存在于两个文件中,分别针对GCC和ECC(intel的编译器).它的定义:

1.在include/linux/compiler-gcc.h中:

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

&a[0]是一个指针,指向不同于这个数组的类型.

#define __must_be_array(a) \

BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0])))

/* Force a compilation error if condition is true, but also produce a

result (of value 0 and type size_t), so the expression can be used

e.g. in a structure initializer (or where-ever else comma expressions

aren't permitted). */

当条件为真时强制产生一个编译错误,但也要产生一个结构(值0和size_t类型),这个表达式可以用在例如在结构体初始化程序(或是在不允许使用逗号表达式的地方).

#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1)

__builtin_types_compatible_p:

gcc内嵌函数用于判断一个变量的类型是否为某指定的类型,假如是就返回1,否则返回0。

它返回0或者1的结果,把它代入到BUILD_BUG_ON_ZERO定义中就可以发现,当返回值为0时,BUILD_BUG_ON_ZERO就变成了

#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1]) - 1)

显然,此时BUILD_BUG_ON_ZERO这个宏将返回0。而当__builtin_types_compatible_p为1时,BUILD_BUG_ON_ZERO就变成了

#define BUILD_BUG_ON_ZERO(e) (sizeof(char[-1]) - 1)

显然会造成语法错误,这也是注释中说明"Force a compilation error"的原因。

而这个char的定义在同文件中可以找到,如下:

extern const char linux_banner[];

那么这个linux_banner[]又是什么呢?

在init/version.c中有如下的定义:

/* FIXED STRINGS! Don't touch! */

const char linux_banner[] =

"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"

LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";

2.在include/linux/compiler-intel.h中:

/* Intel ECC compiler doesn't support __builtin_types_compatible_p() */

因为Intel的ECC编译器不支持__builtin_types_compatible_p所以直接定义为0

#define __must_be_array(a) 0

以下搜自网络:

在这里__builtin_types_compatible_p是gcc内置的一个定义,对它的作用有这样一个说明:

— Built-in Function: int __builtin_types_compatible_p(type1, type2)

You can use the built-in function __builtin_types_compatible_p to determine whether two types are the same.

This built-in function returns 1 if the unqualified versions of the types type1and type2(which are types, not expressions) are compatible, 0 otherwise. The result of this built-in function can be used in integer constant expressions.

This built-in function ignores top level qualifiers (e.g., const, volatile). For example, int is equivalent to const int.

The type int[] and int[5] are compatible. On the other hand, int and char * are not compatible, even if the size of their types, on the particular architecture are the same. Also, the amount of pointer indirection is taken into account when determining similarity. Consequently, short * is not similar to short **. Furthermore, two types that are typedefed are considered compatible if their underlying types are compatible.

An enum type is considered to be compatible with another enum type. For example, enum {foo, bar} is similar to enum {hot, dog}.

You would typically use this function in code whose execution varies depending on the arguments' types. For example:

#define foo(x)                                                  \

({                                                           \

typeof (x) tmp;                                              \

if (__builtin_types_compatible_p (typeof (x), long double)) \

tmp = foo_long_double (tmp);                              \

else if (__builtin_types_compatible_p (typeof (x), double)) \

tmp = foo_double (tmp);                                   \

else if (__builtin_types_compatible_p (typeof (x), float)) \

tmp = foo_float (tmp);                                    \

else                                                         \

abort ();                                                 \

tmp;                                                        \

})

linux函数嵌套,gcc内嵌函数__builtin_types_compatible_p 在内核中的一个实例...相关推荐

  1. 8.局部变量/全局变量global/内嵌函数/闭包nonlocal

    函数:有返回值 过程:无返回值 注解:在python中,只有函数(每个函数都有返回值),没有过程>>> def hello():print("first")> ...

  2. day4 高阶函数 嵌套函数 装饰器 内置函数 列表生成式 迭代器 生成器

    一.函数即变量 1.赋值效果图 a = 1  b = a def func(): print('hello') func 是函数名,相当于变量名,print('hello')是函数体,相当于变量的值, ...

  3. python中闭包函数_Python的闭包问题(关于内嵌函数引用闭包函数的变量问题)

    一.闭包: 记得:闭包的特性就是:内嵌函数会保存它引用的外围函数的变量值. 闭包概念:在一个内部函数中,对外部作用域的变量进行引用,(并且一般外部函数的返回值为内部函数),那么内部函数和被引用的变量等 ...

  4. python内置函数调整_python - 内置函数

    一.内置函数 嵌入到主调函数中的函数称为内置函数,又称内嵌函数. 作用是提高程序的执行效率,大多编程语言都有自己的内置函数. 1.作用域相关 deffunc(): name= 'alex' print ...

  5. function函数嵌套 matlab_Matlab函数进阶:使用匿名函数和内嵌函数处理多变量传递问题...

    Matlab 函数进阶: 使用匿名函数 (Anonymous Function) 和内嵌函数 (Nested Function) 处理多变量传递问题 (Matlab 7.0 以上 ) 问题: 有一个多 ...

  6. Makefile所有内嵌函数

    一.文本处理函数 以下是GNU make内嵌的文本(字符串)处理函数. 1       $(subst FROM,TO,TEXT) 函数名称:字符串替换函数-subst. 函数功能:把字串" ...

  7. 零基础入门学习Python(19)-内嵌函数和闭包

    global关键字 全局变量的作用域是整个模块,也就是代码段内所有的函数内部都可以访问到全局变量 注意,在函数内部仅仅去访问全局变量就好,不要试图去修改它,如果随意修改全局变量的值,很容易牵一发而动全 ...

  8. 课时20:内嵌函数和闭包

    目录: 一.global关键字 二.内嵌函数 三.闭包 四.课时20课后习题及答案 ******************** 一.global关键字 ******************** 全局变量 ...

  9. 使用匿名函数和内嵌函数处理多变量传递问题

    问题:有一个多变量函数f(abcx),现需要分别在a=a0b=b0c=c0和a=a1b=b1c=c1的条件下对f(abcx)进行某一操作. 此类问题常在数值积分时出现. 解决方案: 1. 使用全局变量 ...

最新文章

  1. swift tableview 侧滑删除
  2. 第一次投稿怎么选杂志?
  3. iOS中 动态启动图GIF的简单设置 韩俊强的博客
  4. python加密程序_Python 简单的可逆加密程序
  5. 【图像处理基础知识】python+opencv显示中文
  6. vue 设置每个页面的title
  7. 多Resource文件的相互引用与合并问题及其解决方案
  8. Lottie动画的使用
  9. HC32F4 CRC32校验(附软件CRC32校验)
  10. 阿里云DataV数据过滤器取Value值大于等于25的数据(1)
  11. 评价好的良心浏览器,最后一个比360浏览器好用
  12. jetpack之workManager官方文档解析
  13. SpringBoot整合Quartz==适用于单任务多任务
  14. 怎么使用ping命令进行连通性测试
  15. 判断将输入字母,进行大写转小写,小写转大写
  16. c语言舍弃字符串的前一部分,C语言札记
  17. 多级弹出菜单jQuery插件ZoneMenu
  18. 被谷歌出卖定位信息成“嫌疑犯”,花了大价钱才避免窦娥冤 | 一个自行车爱好者自述...
  19. linux平台的字典,Linux系统中安装CLI的字典sdcv
  20. win10右键创建md文件

热门文章

  1. 每日linux命令学习-历史指令查询(history、fc、alias)
  2. 缺陷管理系统mantisbt环境搭建
  3. jdbc连接池连不上mysql80_JDBC MySql连接池实践可避免连接池耗尽-问答-阿里云开发者社区-阿里云...
  4. mysql库与oracle库的区别_开源数据库Oracle与MySQL的SQL语法区别
  5. ICT学习笔记(1) 网络以及网络模型的相关知识
  6. c 与java联调rsa加密问题_关于前端RSA加密和解密的研讨
  7. qt qthead里如何响应信号_QT使用教程(五)之程序编写
  8. sql server代理无法启动_谁说前端不需要懂Nginx反向代理与负载均衡
  9. hive中导入csv,本地CSV导入hive表
  10. c语言上机考试设计题及答案,C语言程序设计基础上机考试一题目及参考答案.doc...