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 ...
随机推荐
- .net接口学习笔记
1.接口的声明 接口的声明不能包含:数据成员,静态变量:只能包含如下类型的静态成员函数的声明:方法,属性,事件,索引器.声明中不能包含任何实现的代码,而在每个成员成名的主体后,必须使用分号. 接口声明 ...
- asp.net.web如何简单生成和保存二维码图片的例子
首先,要有生成二维码图片,需要二维码生成的类库,到官网下载thoughtWorks.QRCode.dll 例子的步骤: 1.创建项目QRCodeTest1,选择asp.net.web窗体应用程序
- 回文串---Best Reward
HDU 3613 Description After an uphill battle, General Li won a great victory. Now the head of state ...
- 缓存技术比拼:Redis与Memcached的同与不同
转至:http://developer.51cto.com/art/201603/507980.htm 在今天的文章中,我们将探讨Redis(REmote DIctionary Server).Red ...
- SharpGL学习笔记(十四) 材质:十二个材质球
材质颜色 OpenGL用材料对光的红.绿.蓝三原色的反射率来近似定义材料的颜色.象光源一样,材料颜色也分成环境.漫反射和镜面反射成分,它们决定了材料对环境光.漫反射光和镜面反射光的反射程度.在进行光照 ...
- 设计模式之Builder (创建者模式)的一些个人理解(转)
对于Builder模式很简单,但是一直想不明白为什么要这么设计,为什么要向builder要Product而不是向知道建造过程的Director要.刚才google到一篇文章,总算清楚了.在这里转贴一下 ...
- C#进制转换
//十进制转二进制 Console.WriteLine(Convert.ToString(69, 2)); //十进制转八进制 Console.WriteLine(Convert.ToString(6 ...
- SharePoint 2010 文档管理之点击次数
前言:很多场景下,我们都需要对一篇文章或者文档的点击次数进行统计,然而SharePoint本身并没有给我们设计这样一个字段,所以我们需要通过简单的字段开发来实现这样一个功能. 一.创建项目: 1. 创 ...
- [ html canvas 模仿支付宝刮刮卡效果 ] canvas绘图属性 模仿支付宝刮刮卡效果实例演示
<!DOCTYPE html> <html lang='zh-cn'> <head> <title>Insert you title</title ...
- 在Android开发中使用Ant 一:环境的搭建及入门
配置Ant环境 下载Ant:http://ant.apache.org/bindownload.cgi 在windows上应该选择zip压缩包,将zip压缩包解压到一个目录. 打开系统环境变量,在系统 ...