min宏定义探究(linux)

来源:互联网 发布:网络攻防技术与实践 编辑:程序博客网 时间:2024/05/21 23:33


$ 编译成功!

5、使用typeof和({})实现min,避免了副作用

#define min(X,Y) /
({ /
typeof(X) __x=(X), __y=(Y); /
(__x<__y)?__x:__y; /
})

使用传统的min会出现问题的例子:

int x = 1, y = 2;;
int main()
{
   printf("min=%d/n", min(x++, y++));
   printf("x = %d, y = %d/n", x, y);
}

它被扩展为
引用:
int x = 1, y = 2;;
int main()
{
   printf("min=%d/n", ({
       typeof(x) __x = (x++), __y = (y++); /* 定义了两个整形变量 */
       (__x<__y)?__x:__y;
   })
   );
   printf("x = %d, y = %d/n", x, y);
}


在执行min(x++, y++)期间,x++和y++只执行了一次,因而结果是正确的。

附录1、旧版本的的GCC中的的解决方法
旧版本的GCC提供了两个内置的运算操作符:<?>?<?返回两个操作数中较小的一个,>?返回两个操作数中较大的一个,使用这两个操作符定义的min如下:

#define min(x, y) ((x) <? (y))
#define max(x, y) ((x) >? (y))
但是新版本的GCC文档中宣称:现在这两个运算操作符已经过时了,建议大家不要使用。

附录2、C++中使用template的解决方法
template <class type>
type min(type a, type b)
{
     return a < b ? a : b;
}

来源: http://www.chinaunix.net/jh/23/934870.html


add linux kernel min, max define:
include/linux/kernel.h

/*
 * min()/max() macros that also do
 * strict type-checking.. See the
 * "unnecessary" pointer comparison.
 */

#define min(x,y) ({ /
        typeof(x) _x = (x); /
        typeof(y) _y = (y); /
        (void) (&_x == &_y); /
        _x < _y ? _x : _y; })

#define max(x,y) ({ /
        typeof(x) _x = (x); /
        typeof(y) _y = (y); /
        (void) (&_x == &_y); /
        _x > _y ? _x : _y; })

 

 
   Min和Max宏:
  
  /*
  * min()/max() macros that also do
  * strict type-checking.. See the
  * "unnecessary" pointer comparison.
  */

  #define min(x,y) ({ typeof(x) _x = (x); typeof(y) _y = (y); (void) (&_x == &_y); _x < _y ? _x : _y; })
  #define max(x,y) ({ typeof(x) _x = (x); typeof(y) _y = (y); (void) (&_x == &_y); _x > _y ? _x : _y; })
  /*
  * ..and if you can't take the strict
  * types, you can specify one yourself.
  *
  * Or not use min/max at all, of course.
  */

  #define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
  #define max_t(type,x,y) ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
  不是感觉跟我们用的有些不一样啊:
  (void) (&_x == &_y);
  (void) (&_x == &_y)这句话本身都执行程序来讲完全是一句废话,它的作用在于,本身我们无法做这样的操作typeof(_x)==typeof(_y),所以故意判断他们2个的地址指针是否相等,显然是不可能相等,但是如果_x和_y的类型不一样,其指针类型也会不一样,2个不一样的指针类型进行比较操作,会抛出一个编译警告。也就是说char *p; int *q; 然后p==q;,这个判断因为一个是char*一个是int*,会在编译时产生一个warning。巧妙就巧妙在这里。
  由于内核是很多开发着一起开发的,其中还有一些其他的实现,就跟我们平常用的一样:
  #define min(a,b) (((a) < (b)) ? (a) : (b))
  试想:
  min(++a,++b) ==> ((++a)<(++b))?(++a):(++b)
  是不是就有问题了,传入的参数被加了两次。

 

转自http://blog.chinaunix.net/u2/76292/showart.php?id=2208324 以此记录

原创粉丝点击