linux内核宏container_of前期准备之gcc扩展关键字typeof
- typeof基本介绍
typeof(x)
这是它的使用方法,x可以是数据类型或者表达式。它的作用时期和sizeof类似,就是它是在编译器从高级语言(如C语言)翻译成汇编语言时起作用,这个很重要,稍后会解释。
当x是数据类型时,它和关键字typedef很相似,只不过typedef是要先定义再使用,而typeof则是可立即使用的,如下:
typedef int INT;
int main(int argc, const char *argv[])
{
INT a;
typeof(int) b; return ;
}
当x是表达式时:
//变量
int a;
typeof(a)b; //数组
int c[];
typeof(c) d;//相当于int d[10];因为c的类型是int *[10] //函数
int foo(void)
{
return ;
} typeof(foo) c;//foo函数指针类型 int (*)(void)
typeof(foo()) d; //foo函数返回类型 int
typeof(foo()) d;这句并不会导致函数foo被调用,上面有讲到它的作用时期和sizeof一样,它仅仅是获得x的数据类型,比如对于sizeof:
int a[];
char len; len = sizeof(a);
在编译器将源码由高级语言转到汇编语言时,sizeof关键字就其到了作用。我们甚至可以认为有点类似宏替换(注意发生的阶段不同),相当于是:
int a[];
char len; len = ;
这一切发生在汇编阶段,typeof也是类似的作用原理,这也就是为什么foo()为什么并没被调用的原因。
- typeof使用需要注意的问题
1.typeof构造中的类型名不能包含存储类说明符,如extern或static。不过允许包含类型限定符,如const或volatile。
static int a = ;
typeof(a)b; //编译没问题,等于int b;
typeof(static int) b; //编译报错 const int a = ;
typeof(a)b = ;//等同于 const int 5;
我的个人理解是extern和static的限定只是影响至链接阶段,而const和volatile影响直至执行阶段。好像并不怎么合理,暂时就记录下来吧。
2.比较容易忽略的一点,通常:
int *a,b; //原意是定义2个int *的变量a,b。初学者容易犯的错误 //实际要用
int *a, *b; //但是typeof关键字不是这样的
int *a;
typeof(a)b,c; //它就是int *b, *c的意思,它不是简单的宏替换,特别要注意
- 为什么要用typeof,或者说typeof的使用带来了什么好处
回想我们交换2个变量的方法,最先想到的是利用第三个变量作为中间变量。
void swap(int a,int b)
{
int tmp; tmp = b;
b = a;
a = tmp;
}
如果我要交换的是2个char型变量呢?那岂不是又要写一个函数,太麻烦了。那么强大的typeof来了
#define SWAP(a, b) {\
typeof(a) _t=a;\
a=b;\
b=_t;}
一个宏搞定所有基本类型数据交换,甚至是构造类型。妈妈再也不用担心我写到手抽筋了。
参考:
http://module77.is-programmer.com/posts/22102.html
http://gcc.gnu.org/onlinedocs/gcc/Typeof.html
linux内核宏container_of前期准备之gcc扩展关键字typeof的更多相关文章
- linux内核宏container_of
首先来个简单版本 /* given a pointer @ptr to the field @member embedded into type (usually * struct) @type, r ...
- Linux内核中container_of宏的详细解释
上一节拒绝造轮子!如何移植并使用Linux内核的通用链表(附完整代码实现)我们在分析Linux内核链表的时候注意到内核在求解结构体偏移的时候巧妙的使用了container_of宏定义,今天我们来详细剖 ...
- Linux内核宏DEVICE_ATTR使用
1.前言 在Linux驱动程序编写中,使用DEVICE_ATTR宏,可以定义一个struct device_attribute设备属性,并使用sysfs的API函数,便可以在设备目录下创建出属性文件, ...
- linux内核代码container_of
它的作用显而易见,那就是根据一个结构体变量中的一个域成员变量的指针来获取指向整个结构体变量的指针. typedef unsigned int __kernel_size_t; typedef __ke ...
- Linux内核中container_of函数详解
http://www.linuxidc.com/Linux/2016-08/134481.htm
- 嵌入式C语言自我修养 01:Linux 内核中的GNU C语言语法扩展
1.1 Linux 内核驱动中的奇怪语法 大家在看一些 GNU 开源软件,或者阅读 Linux 内核.驱动源码时会发现,在 Linux 内核源码中,有大量的 C 程序看起来“怪怪的”.说它是C语言吧, ...
- Linux 内核中的 GCC 特性
https://www.ibm.com/developerworks/cn/linux/l-gcc-hacks/ GCC 和 Linux 是出色的组合.尽管它们是独立的软件,但是 Linux 完全依靠 ...
- GCC扩展(转--对看kernel代码有帮助
http://my.oschina.net/senmole/blog?catalog=153878 Linux Kernel的代码,上次就发现一个结构体的定义形式看不懂,后来才知道它用的不是标准的AN ...
- linux内核中链表代码分析---list.h头文件分析(一)【转】
转自:http://blog.chinaunix.net/uid-30254565-id-5637596.html linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17 ...
随机推荐
- 对一个或多个实体的验证失败。有关详细信息,请参见“EntityValidationErrors”属性。
问题原因: 1.非空列未插入值错误 2.内容长度超过列最大长度(超过数据库设置长度,或者自定义长度“[StringLength(50, MinimumLength = 6, ErrorMessage ...
- 基于吉日嘎底层架构的Web端权限管理操作演示-用户管理
相信博客园的朋友对吉日嘎拉都不陌生,相信很多人也买了他的源码,应用于自己的项目. 但是你有没有过一个困惑? 那就是:没有一个基于网页的权限管理界面. 今天,这一切都不再是问题,我花了3年时间研究学习并 ...
- 在一个XAML中点击按钮,界面跳转到另一个XAML界面方法
private void ButtonGo_camerapage(object sender, RoutedEventArgs e) { this.Content = new cameraPage() ...
- 泛函编程(14)-try to map them all
虽然明白泛函编程风格中最重要的就是对一个管子里的元素进行操作.这个管子就是这么一个东西:F[A],我们说F是一个针对元素A的高阶类型,其实F就是一个装载A类型元素的管子,A类型是相对低阶,或者说是基础 ...
- css样式reset
初始化样式. @CHARSET "UTF-8"; body,ur,ol,li,p,h1,h2,h3,h4,h5,h6,form,fieldset,table,td,img,div, ...
- ASP.NET Web API 通过Authentication特性来实现身份认证
using System; using System.Collections.Generic; using System.Net.Http.Headers; using System.Security ...
- ORACLE 中ROWNUM用法总结!
ORACLE 中ROWNUM用法总结! 对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<.<=.!=) ...
- 【翻译】Netscaler真实表现性能调整
源地址:https://msandbu.wordpress.com/2014/10/31/netscaler-and-real-performance-tuning/ 作者显然不是以英语为母语的,所以 ...
- mybatis hellworld
用maven来进行搭建项目的~~ 1. 搭建环境 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" x ...
- 项目、SVN clean的一些事
1.如果你发现你的文件修改了.Tomcat也重新了,但访问的还是旧的文件,这个时候你需要clean下你的项目. Clean will discard all build problems and bu ...