linux内核中的typeof

来源:互联网 发布:php数组添加元素的函数 编辑:程序博客网 时间:2024/05/23 21:57

http://blog.csdn.net/ce123_zhouwei/article/details/8458114

http://blog.chinaunix.net/uid-20758472-id-1876971.html

今天分析内核时又看到了typeof,只知道它大概是返回变量的类型,后来上网查了下发现这个关键字在linux中用的非常多。如果你对sizeof很熟悉的话,那么大可进行类推,sizeof(exp)返回的是exp的数据类型大小,那么typeof(exp.)返回的就是exp的数据类型。下面是linux内核中typeof的一些例子。include/linux/kernel.h

[plain] view plaincopyprint?
  1. /*  
  2.  * min()/max() macros that also do  
  3.  * strict type-checking.. See the  
  4.  * "unnecessary" pointer comparison.  
  5.  */  
  6. #define min(x,y) ({ \  
  7.     typeof(x) _x = (x); \  //_x的数据类型和x一样  
  8.     typeof(y) _y = (y); \  
  9.     (void) (&_x == &_y);        \  
  10.     _x < _y ? _x : _y; })  
  11.   
  12.   
  13. #define max(x,y) ({ \  
  14.     typeof(x) _x = (x); \  
  15.     typeof(y) _y = (y); \  
  16.     (void) (&_x == &_y);        \  
linux/include/asm-arm/uaccess.h
[plain] view plaincopyprint?
  1. #define get_user(x,p)                           \  
  2.     ({                              \  
  3.         const register typeof(*(p)) __user *__p asm("r0") = (p);\   //__p的数据类型和*(p)的指针数据类型是一样的,__p = p  
  4.         register typeof(*(p)) __r2 asm("r2");           \   //__r2的数据类型和*(p)的数据类型是一样的  
  5.         register int __e asm("r0");             \  
  6.         switch (sizeof(*(__p))) {               \  
  7.         case 1:                         \  
  8.             __get_user_x(__r2, __p, __e, 1, "lr");      \  
  9.                 break;                      \  
  10.         case 2:                         \  
  11.             __get_user_x(__r2, __p, __e, 2, "r3", "lr");    \  
  12.             break;                      \  
  13.         case 4:                         \  
  14.                 __get_user_x(__r2, __p, __e, 4, "lr");      \  
  15.             break;                      \  
  16.         case 8:                         \  
  17.             __get_user_x(__r2, __p, __e, 8, "lr");      \  
  18.                 break;                      \  
  19.         default: __e = __get_user_bad(); break;         \  
  20.         }                           \  
  21.         x = __r2;                       \  
  22.         __e;                            \  
  23.     })  
下面写一个小程序示例一下:
[plain] view plaincopyprint?
  1. #include <stdio.h>  
  2.   
  3. typedef struct   
  4. {  
  5.     int x;  
  6.     char y;  
  7. }astruct, * pastrcut;  
  8.   
  9. int main()  
  10. {  
  11.     int sizem, sizew;  
  12.     int x = 3;  
  13.     typeof(&x) m = &x;  
  14.     sizem = sizeof(m);  
  15.     *m = 5;  
  16.     typeof(((astruct *)5)->y) w;  
  17.     sizew = sizeof(w);  
  18.     w = "a";  
  19.     return 1;  
  20. }  

首先看main函数里的m变量,这个变量的类型就是typeof(&x), 由于x是int型的(这里与x是否被赋值一点关系都没有),所以&x应该是int *类型,那么typeof(&x)返回的类型就是int*,所以m自然也就是个int*类型的。

然后我们看w变量,其类型是 typeof(((astruct *)5)->y), 其中astruct是一个被定义的结构类型,其中的y元素是char类型,那么((astruct *)5)->y是啥意思呢?在这里5并不是真正的变量,可以把它理解为一个替代使用的符号,当然这个符号最好是一个数,其意思更可以理解为一个被赋值了的变量,这个数可以是0,3,也可以是8也可以随便什么都可以。那么((astruct *)5)->y仅仅就是表示了y这个变量,所以typeof的结果就是y元素的类型,也就是char。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

typeof关键字是C语言中的一个新扩展。只要可以接受typedef名称,Sun Studio C 编译器就可以接受带有typeof的结构,包括以下语法类别:

  • 声明
  • 函数声明符中的参数类型链表和返回类型
  • 类型定义
  • 类型操作符s
  • sizeof操作符
  • 复合文字
  • typeof实参

编译器接受带双下划线的关键字:__typeof__typeof__。本文中的例子并没有遵循使用双下划线的惯例。从语句构成上看,typeof关键字后带圆括号,其中包含类型或表达式的名称。这类似于sizeof关键字接受的操作数(与sizeof不同的是,位字段允许作为typeof实参,并被解释为相应的整数类型)。从语义上看,typeof 关键字将用做类型名(typedef名称)并指定类型。

使用typeof的声明示例

下面是两个等效声明,用于声明int类型的变量a

typeof(int) a; /* Specifies variable a which is of the type int */ 
typeof('b') a; /* The same. typeof argument is an expression consisting of
character constant which has the type int */

以下示例用于声明指针和数组。为了进行对比,还给出了不带typeof的等效声明。

typeof(int *) p1, p2; /* Declares two int pointers p1, p2 */
int *p1, *p2;

typeof(int) * p3, p4;/* Declares int pointer p3 and int p4 */
int * p3, p4;

typeof(int [10]) a1, a2;/* Declares two arrays of integers */

int a1[10], a2[10];

如果将typeof用于表达式,则该表达式不会执行。只会得到该表达式的类型。以下示例声明了int类型的var变量,因为表达式foo()int类型的。由于表达式不会被执行,所以不会调用foo函数。

extern int foo();
typeof(foo()) var;

使用typeof的声明限制

请注意,typeof构造中的类型名不能包含存储类说明符,如externstatic。不过允许包含类型限定符,如constvolatile。例如,下列代码是无效的,因为它在typeof构造中声明了extern

typeof(extern int) a;

下列代码使用外部链接来声明标识符b是有效的,表示一个int类型的对象。下一个声明也是有效的,它声明了一个使用const限定符的char类型指针,表示指针p不能被修改。

extern typeof(int) b;
typeof(char * const) p = "a";

在宏声明中使用typeof

typeof构造的主要应用是用在宏定义中。可以使用typeof关键字来引用宏参数的类型。因此,在没有将类型名明确指定为宏实参的情况下,构造带有所需类型的对象是可能的。


0 0