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 ...
随机推荐
- C#接口知识大全收藏
第一节 接口慨述 接口(interface)用来定义一种程序的协定.实现接口的类或者结构要与接口的定义严格一致.有了这个协定,就可以抛开编程语言的限制(理论上).接口可以从多个基接口继承,而类或结构可 ...
- [CLR via C#]11. 事件
一. 设计要公开事件的类型 如果类型定义了事件成员,那么类型(或类型实例)就可以通知其他对象发生了一些特定的事情. 例如,Button类提供了一个名为Click的事件.应用程序中的一个或多个对象可能想 ...
- 以对象的方式来访问xml数据表(二)
为什么要以对象的方式来访问xml数据表? 还记得,自己是在一次完成师兄布置的任务时接触到了xml,那时候需要用xml来作为数据文件,保存一个简单的图书管理系统的数据.于是就知道了,可以用xml文件来保 ...
- mssql server提示无权限
mssqlserver在查询系统视图时(如:select * from sys.syscacheobjects),有时会报出如下提示: 消息 300,级别 14,状态 1,第 1 行VIEW SERV ...
- 【C#进阶系列】04 类型基础
关于System.Object 所有类型都从System.Object派生而来. System.Object的公共方法中ToString()一般是返回对象的类型的全名,只有Int32这些类型将其重写后 ...
- css中inline、block、inline-block的区别
http://www.cnblogs.com/fxair/archive/2012/07/05/2577280.html display:inline就是将元素显示为块级元素. block元素的特点是 ...
- bzoj1146整体二分+树链剖分+树状数组
其实也没啥好说的 用树状数组可以O(logn)的查询 套一层整体二分就可以做到O(nlngn) 最后用树链剖分让序列上树 #include<cstdio> #include<cstr ...
- oracle sql 语句优化
(1)选择最有效率的表名顺序(只在基于规则的优化器中有效):Oracle的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理 ...
- C#读写ini文件操作
ini文件,是windows操作系统下的配置文件,ini文件是一种按照特点方式排列的文本文件,它的构成分为三部分,结构如下: [Section1] key 1 = value2 key 1 = val ...
- WampServer搭建php环境可能遇到的问题
WampServer搭建php环境可能遇到的问题 1.安装时报错,缺少 MSVCR100.dll 文件 这是因为wampServer安装时用到的vc库没有更新,要安装更新之后再进行安装,因为之前安装的 ...