C语言中 typeof 关键字是用来定义变量数据类型的。在linux内核源代码中广泛使用。

使用方法

1.当x的类型为是 int 时 _min1变量的数据类型则为 int。

2.当x为一个表达式时(例: x = 3-4), _min1变量的数据类型为这个表达式结果的数据类型。

3. typeof括号中也可以是函数

int function(int, int);
typeof(function(1. 2)) val;

此时val的数据类型为 函数function(int, int)返回值的数据类型,即int类型。(注意: typeof并不会执行函数function)。

局限性: typeof构造中的类型名不能包含存储类说明符,如extern或static。不过允许包含类型限定符,如const或volatile。
    例如,下列代码是无效的,因为它在typeof构造中声明了extern:
          typeof(extern int) a;

经典应用

下面是Linux内核源代码中一个关于typeof实例:

#define min(x, y) ({        \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })

关于其中的:

(void) (&_x == &_y);

很是疑惑,表面看起来,这句话,好像不起作用,算是一句废话,所以去找了一下别人的解释,才大概搞懂是啥意思。

首先,我们此处想要实现的目的是,在计算两个数的最小值之前,希望去判断一下两个值的类型是否一致,而由于C语言本身不支持我们去做类似于这样的操作 typeof(_x)==typeof(_y),所以在此,通过故意判断他们2个的地址指针是否相等,而显然&_x,即x的地址,是不可能等于&_y的,但是这句话(void) (&_x == &_y);使得:如果_x和_y的类型不一样,其指针类型也会不一样,2个不一样的指针类型进行比较操作,则会引起编译器产生一个编译警告,提示你这两个值的类型不同。

比如,如果你编译下面这段代码:

int x = 2;
char y = 3;
int m;
m = min(x,y);

编译的时候,经过预处理后,就会有这样的判断操作:

int * == char *;

因此编译器就会提示你:

warning: comparison of distinct pointer types lacks a cast

所以,这个宏的巧妙之处就在于此。

所以,总结起来就是:

(void) (&_x == &_y); 用于判断输入的两个值的类型是否是一致的。如果不一致,那么编译器就会做出如下警告:warning: comparison of distinct pointer types lacks a cast

【提示】

1. 其实关于min的宏,更好的做法是再加个const,即:

2. (void) (&_x == &_y); 中的void,表示将表达式(&_x == &_y); 所得到的结果(此处肯定是逻辑上的假,值为0)忽略掉。如果不加void,则会提示你这行代码是无意义的,没人用到。

3. 关于min的宏定义,为何这么复杂,而不是用简单的#define min(x,y) ((x) < (y) ? x : y)

因为,如果如此定义,那么对于一些特殊的值传入此宏之后,就会产生一些副作用,产生的结果,就不是我们想要的了,比如:

  min(++a,++b) ==> ((++a)<(++b))?(++a) : (++b)
就使得,a++和b++分别执行了2次,而且min的结果,也不对了。而用上面那个复杂的定义,多加了局部变量_x和_y,就可以避免此类问题了。

参考:

1. GNU 官方手册:https://gcc.gnu.org/onlinedocs/gcc/Typeof.html

2. crifan 的个人网站:http://www.crifan.com/order_min__macro_definition_void_amp__x__amp__y_the_meaning_of/

3. 脚本之家:浅析C语言中typeof关键字用法

4. C语言typeof详解

typeof关键字的更多相关文章

  1. typeof关键字简介 -rtti

    typeof关键字是C语言中的一个新扩展.只要可以接受typedef名称,Sun Studio C 编译器就可以接受带有typeof的结构,包括以下语法类别: 声明 函数声明符中的参数类型链表和返回类 ...

  2. typeof关键字的作用

    http://blog.chinaunix.net/uid-28458801-id-4200573.html 一.typeof详解: 前言:    typeof关键字是C语言中的一个新扩展,这个特性在 ...

  3. c语言中typeof关键字

    为什么因为一个关键字而专门写一篇随笔呢?因为这个关键字在Linux里面地位非同一般!这个关键字typeof在linux内核里面使用非常广泛! 下面这两个等效声明,用于声明int类弄的变量atypeof ...

  4. C#中使用typeof关键字和GetType()获取类的内部结构(反射机制)

    一.问题描述 java有反射机制,C#也有反射机制,在C#中typeof关键字用于获取类型的System.Type对象,该对象的GetMethods()方法可以得到类型中定义的方法对象的计集合,调用方 ...

  5. typeof()关键字

    typeof是GNU c标准的关键字. typeof()的作用是自动推导出括号中表达式的数据类型. #include <stdio.h> void func1(void) { ; type ...

  6. TypeScript 0.9.1 发布,新增 typeof 关键字

    TypeScript 0.9.1 发布了,该版本提升了编译器和语言的性能,增加新的语言特性 typeof ,更好的 this 处理等.详细介绍请看发行说明. TypeScript 是微软新推出的一种语 ...

  7. 023使用typeof关键字获取类内部结构

    private void button1_Click(object sender, EventArgs e) { Focus(); string a=txtType.Text; // Type typ ...

  8. linux内核宏container_of前期准备之gcc扩展关键字typeof

    typeof基本介绍 typeof(x) 这是它的使用方法,x可以是数据类型或者表达式.它的作用时期和sizeof类似,就是它是在编译器从高级语言(如C语言)翻译成汇编语言时起作用,这个很重要,稍后会 ...

  9. C语言typeof详解 offsetof

    http://blog.chinaunix.net/uid-28458801-id-4200573.html 前言:    typeof关键字是C语言中的一个新扩展,这个特性在linux内核中应用非常 ...

随机推荐

  1. linux free命令详解和使用实例(查看内存使用率)

    转载:http://www.jb51.net/LINUXjishu/152017.html 1.命令格式: free [参数] 2.命令功能: free 命令显示系统使用和空闲的内存情况,包括物理内存 ...

  2. STL - 常用关联容器代码 - set & multiset

    代码如下: /* 5. set & multiset */ set<string> cities{ "Braunschweig", "Hanover& ...

  3. ffmpeg & mplayer & vlc 手册(转)

    如何基于FFMPEG和SDL写一个少于1000行代码的视频播放器 http://blog.sina.com.cn/s/blog_51396f890100nd91.html http://lanhy20 ...

  4. 弹出式菜单css

    #v_box { width: 700px; height: 610px; background: #fff; position: fixed; top: 50%; left: 50%; z-inde ...

  5. Eddy&#39;s digital Roots

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission ...

  6. Android:No implementation found for native(转)

    解决方法: 1.检查native c code的定义: JNIEXPORT void Java_com_example_something_MyClass_getMyString(JNIEnv * e ...

  7. Mqtt ----心跳机制

    心跳机制 Keep Alive指定连接最大空闲时间T,当客户端检测到连接空闲时间超过T时,必须向Broker发送心跳报文PINGREQ,Broker收到心跳请求后返回心跳响应PINGRESP.若Bro ...

  8. 手动集成OWIN

    1.Install-Package Microsoft.AspNet.Identity.Owin Owin的很大亮点之一就是它可以让我们的ASP.NET 网站摆脱IIS,但是毕竟大多数的ASP.NET ...

  9. 网站收到的url请求链接,字母全部变为小写

    http://www.ithao123.cn/content-5360465.html

  10. spring中ApplicationContext

    1 spring 容器应用上下文:ApplicationContext 主要的实现类是 ClassPathXmlApplicationContext 和 FileSystemXmlApplicatio ...