Linux内核中是怎么实现min和max函数

时间:2022-06-05 22:50:38

Linux内核代码有很多很经典的代码,仔细去看看,可以学到很多知识。今天说说Linux是怎么实现min和max的。max和min函数都是比较常用的,可以用函数,或者利用宏去实现,一般我们会这样去写:

1 #define
min(x,y) ((x)>(y)?(y):(x))
2 #define
max(x,y) ((x)>(y)?(x):(y))

但是上面的写法是有副作用的。比如输入

1 minval
= min(x++, y);

替换宏之后,代码变成

1 minval
= ((x++)>(y)?(y):(x++))

可以看出,如果x是最小值,那么它加了两次,很明显是不对的。现在看看Linux内核是怎么实现min和max宏的。

01 /*
02  * min()/max() macros that also do
03  * strict type-checking.. See the
04  * "unnecessary" pointer comparison.
05  */
06  #define min(x, y) ({                            \
07          typeof(x) _min1 = (x);                  \
08          typeof(y) _min2 = (y);                  \
09          (void) (&_min1 == &_min2);              \
10          _min1 < _min2 ? _min1 : _min2; })
11   
12  #define max(x, y) ({                            \
13          typeof(x) _max1 = (x);                  \
14          typeof(y) _max2 = (y);                  \
15          (void) (&_max1 == &_max2);              \
16          _max1 > _max2 ? _max1 : _max2; })
17   
18  #define min3(x, y, z) ({                        \
19          typeof(x) _min1 = (x);                  \
20          typeof(y) _min2 = (y);                  \
21          typeof(z) _min3 = (z);                  \
22          (void) (&_min1 == &_min2);              \
23          (void) (&_min1 == &_min3);              \
24          _min1 < _min2 ? (_min1 < _min3 ? _min1 : _min3) : \
25                  (_min2 < _min3 ? _min2 : _min3); })
26   
27  #define max3(x, y, z) ({                        \
28          typeof(x) _max1 = (x);                  \
29          typeof(y) _max2 = (y);                  \
30          typeof(z) _max3 = (z);                  \
31          (void) (&_max1 == &_max2);              \
32          (void) (&_max1 == &_max3);              \
33          _max1 > _max2 ? (_max1 > _max3 ? _max1 : _max3) : \
34                  (_max2 > _max3 ? _max2 : _max3); })

里面有很多东西都没见过,但是它能解决传统的min/max宏带来的副作用。下面来一一说一下上面宏的含义:

  1. typeof(xxx)含义。
    typeof(xxx)的含义是用来获取xxx的类型,比如上面的

    1 typeof(x)
    _min1 = (x);

    typeof(x)是获得x的类型,上面的含义相当于

    1 int _min1 = (x);
  2. ({XXXX})含义。
    ({XXXX})类似与C中的逗号表达式,XXXX可以包含有多条语句(可以是变量定义、复杂的控制语句),该表达式的值为XXXX中的最后一条语句的值。比如下面

    01 #include
    <iostream>
    02  
    03 using namespace std;
    04  
    05 int main(){
    06     int lastValue = 0;
    07     lastValue = ({
    08         int x = 1, y = 10;
    09         for(int i = 1; i <= y; i++){
    10             x *= i;
    11         }
    12         x;
    13     });
    14  
    15     cout << lastValue << endl;
    16     return 0;
    17 }

    结果是10的阶乘值。

结合了type和({})可以很好的消除宏的副作用。比如上面的

1 minval
= min(x++, y);

如果代入了Linux内核中的min宏,扩展之后会变成:

1 minval
= ({                            \
2          typeof(x) _min1 = (x++);                  \
3          typeof(y) _min2 = (y);                  \
4          (void) (&_min1 == &_min2);              \
5          _min1 < _min2 ? _min1 : _min2; })

可以看到,x只被加了一次,如果x是最小值,结果是正确的。

本博客文章除特别声明,全部都是原创!
尊重原创,转载请注明: 转载自过往记忆(http://www.iteblog.com/)
本文链接地址: 《Linux内核中是怎么实现min和max函数》(http://www.iteblog.com/archives/237)