min宏的学习

1、先上实现代码:

#define __min(t1, t2, min1, min2, x, y) ({      
    t1 min1 = (x);                  
    t2 min2 = (y);                  
    (void) (&min1 == &min2);            
    min1 < min2 ? min1 : min2; })
#define min(x, y)                   
    __min(typeof(x), typeof(y),         
          __UNIQUE_ID(min1_), __UNIQUE_ID(min2_),   
          x, y)

__UNIQUE_ID(min1_)含义是制造一个唯一的标识符:__UNIQUE_ID_min1_0

__UNIQUE_ID(min2_)含义是制造一个唯一的标识符:__UNIQUE_ID_min2_1

2、为什么把x,y赋值给_min1和_min2然后返回_min1和_min2,而不直接写成(x) < (y)? (x) :(y)呢?这个就是最经典的C语言课本中所说的那个所谓的++的问题了,假如我写成min(a++,b++),展开成宏就变成了(a++) < (b++)? (a++) :(b++)了,究竟a和b各自++了多次,所以我们一定要先把它们赋值给两个局部变量,这样就没有这个问题了。

3、 (void) (&min1 == &min2); 这一行有啥用?检查两个数类型是否匹配,不匹配编译器会报错的,注意必须是地址之间的判等才是类型比较,如果是值的话,那就是单纯的比较数值了和类型就无关了,所以这里要转换成地址,

      另外再将结果强转为void,也是加强说明这是一个类型比较,不可以用作右值,通过void显式丢弃一个表达式的值,否则有些编译器会就此给出警告信息)。(void) (&_x == &_y); 中的void,表示将表达式(&_x == &_y); 所得到的结果( 如果是逻辑上的假,值为0)忽略掉。如果不加void,则会提示你这行代码是无意义的,没人用到,有些编译器会产生警告信息

4、为了便于研究,我把涉及到的宏全部提炼出来,写了一个测试程序:

#include <stdio.h>                                                                                 
#define ___PASTE(a,b) a##b
#define __PASTE(a,b) ___PASTE(a,b)
#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
#define __min(t1, t2, min1, min2, x, y) ({      
        t1 min1 = (x);                  
        t2 min2 = (y);                  
        (void) (&min1 == &min2);            
        min1 < min2 ? min1 : min2; })
#define min(x, y)                   
    __min(typeof(x), typeof(y),         
            __UNIQUE_ID(min1_), __UNIQUE_ID(min2_),   
            x, y)


int main(int argc, char *argv[])
{
    int a=10,b=20;
    int c=min(a,b);
    printf("c=%d
",c);

    return 0;
}

5、__COUNTER__是GCC内置的一个累加器,每次调用都会在以前的基础上加1,从0开始计数。

6、这是解开宏后的源码:

int main(int argc, char *argv[])
{
 int a=10,b=20;
 int c=({ typeof(a) __UNIQUE_ID_min1_0 = (a); typeof(b) __UNIQUE_ID_min2_1 = (b); (void) (&__UNIQUE_ID_min1_0 == &__UNIQUE_ID_min2_1); __UNIQUE_ID_min1_0 < __UNIQUE_ID_min2_1 ? __UNIQUE_ID_min1_0 : __UNIQUE_ID_min2_1; });
 printf("c=%d
",c);
原文地址:https://www.cnblogs.com/litifeng/p/7691837.html