typeof关键字

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详解

时间: 2025-01-02 02:48:21

typeof关键字的相关文章

转:C语言中的typeof关键字

http://blog.csdn.net/wslong/article/details/7728811 typeof关键字是C语言中的一个新扩展. typeof的参数可以是两种形式:表达式或类型. 下面是使用表达式的的例子: typeof(x[0](1) 这里假设x是一个函数指针数组,这样就可以得到这个函数返回值的类型了. 如果将typeof用于表达式,则该表达式不会执行.只会得到该表达式的类型. 以下示例声明了int类型的var变量,因为表达式foo()是int类型的.由于表达式不会被执行,所

typeof关键字简介 -rtti

typeof关键字是C语言中的一个新扩展.只要可以接受typedef名称,Sun Studio C 编译器就可以接受带有typeof的结构,包括以下语法类别: 声明 函数声明符中的参数类型链表和返回类型 类型定义 类型操作符s sizeof操作符 复合文字 typeof实参 编译器接受带双下划线的关键字:__typeof和__typeof__.本文中的例子并没有遵循使用双下划线的惯例.从语句构成上看,typeof关键字后带圆括号,其中包含类型或表达式的名称.这类似于sizeof关键字接受的操作数

typeof关键字的作用

http://blog.chinaunix.net/uid-28458801-id-4200573.html 一.typeof详解: 前言:    typeof关键字是C语言中的一个新扩展,这个特性在linux内核中应用非常广泛.(其实这和C++的auto关键字和可以推断decltype关键字相当类似) 二.实例: 1,把y定义成x指向的数据类型: typeof(*x) y; 2,把y定义成x指向数据类型的数组: typeof(*x) y[4]; 3,把y定义成一个字符指针数组:        

c语言中typeof关键字

为什么因为一个关键字而专门写一篇随笔呢?因为这个关键字在Linux里面地位非同一般!这个关键字typeof在linux内核里面使用非常广泛! 下面这两个等效声明,用于声明int类弄的变量atypeof(int) a;typeof('b') a; //相当于获取'b'的类型,定义一个变量a 下面用于声明指针和数组typeof(int*) p1,p2;typeof(p1) p2  //p1与p2的类型一致int *p1,*p2; typeof(int [10]) a1,a2;int a1[10],a

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

一.问题描述 java有反射机制,C#也有反射机制,在C#中typeof关键字用于获取类型的System.Type对象,该对象的GetMethods()方法可以得到类型中定义的方法对象的计集合,调用方法集合中每个方法对象的GetParameters()可以得到每个方法的参数集合,但是需要引用Reflection命名空间. 获取System.Type对象有两种方法:第一种是用typeof关键字,第二种是用对象引用调用GetType()方法 1.System.Type type =  typeof(

typeof()关键字

typeof是GNU c标准的关键字. typeof()的作用是自动推导出括号中表达式的数据类型. 1 #include <stdio.h> 2 3 void func1(void) 4 { 5 int a = 1; 6 typeof(int *)pa = &a;//pa的数据类型为int型的指针 7 8 printf("pa:\t%p\n", pa); 9 printf("&a:\t%p\n", &a); 10 printf(&

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

typeof基本介绍 1 typeof(x) 这是它的使用方法,x可以是数据类型或者表达式.它的作用时期和sizeof类似,就是它是在编译器从高级语言(如C语言)翻译成汇编语言时起作用,这个很重要,稍后会解释. 当x是数据类型时,它和关键字typedef很相似,只不过typedef是要先定义再使用,而typeof则是可立即使用的,如下: 1 typedef int INT; 2 int main(int argc, const char *argv[]) 3 { 4 INT a; 5 typeo

C#关键字学习

第一部分 一.访问关键字:base,thisbase:访问基类的成员,用于从派生类中访问基类的成员, 1.调用基类上已经被重写的方法. 2.指定创建派生类实例时应调用的基类构造函数. (对基类的访问只能在派生类的构造函数实例的方法和实例的属性访问器中)   属性访问器:get,set函数.不能在静态方法中使用base关键字. 例: 在子类的方法中写 base.GetInfo();调用基类的方法. 基类中的构造函数重载了,Mybase()和Mybase(int i); 在子类的构造函数中publi

C语言typeof详解

前言:     typeof关键字是C语言中的一个新扩展,这个特性在linux内核中应用非常广泛. 一,说明     typeof的参数可以是两种形式:表达式或类型. 1,表达式的的例子:         typeof(x[0](1)         这里假设x是一个函数指针数组,这样就可以得到这个函数返回值的类型了.         如果将typeof用于表达式,则该表达式不会执行.只会得到该表达式的类型.         以下示例声明了int类型的var变量,因为表达式foo()是int类型