• 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构造中的类型名不能包含存储类说明符,如externstatic。不过允许包含类型限定符,如constvolatile
        例如,下列代码是无效的,因为它在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详解

  • 相关阅读:
    python
    ASCII码表
    maven使用阿里云maven库
    eclipse中使用maven的 maven install
    软件项目版本号的命名规则及格式
    win7局域网内共享文件夹及安全设置
    restful返回 json数据的JavaBean设计
    关于StringUtils类isEmpty、isNotEmpty、isBlank、isNotBlank针对null、空字符串和空白字符(如空格、制表符)的区别
    maven如何引入servlet-api和jsp-api
    NetBeans的(默认)快捷键
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/7492318.html
Copyright © 2020-2023  润新知