$ 编译成功!
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 以此记录