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; })
(void) (&_x == &_y)
这句不是为了判断两个变量的地址是否相等,而是为了判断两个变量的类型是否相同;如果类型不同,编译阶段,编译器为告警!
------------------------------------------------------
#include <stdio.h>/* 使用该宏时,如果不关心返回值,没有圆括号()也可以,但是{}是必须的 */
#define min(x, y) { \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; }
int main ()
{
min(10, 20);
if (1)
min(10, 20);
return 0;
}
------------------------------------------------------
#include <stdio.h>/*
* 用该宏时,如果关心返回值,就必须要圆括号()
* 最后一句是该宏的返回值
*/
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
int main ()
{
int ret;
ret = min(10, 20);
printf("ret = %d\n", ret);
return 0;
}
------------------------------------------------------
#include <stdio.h>
/*
* 检测变量类型是否相同
* (void) (&_min1 == &_min2);
*/
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
int main ()
{
int ret;
int i;
char j;
ret = min(i, j);
printf("ret = %d\n", ret);
return 0;
}
------------------------------------------------------
#include <stdio.h>
/*
* 防止类似i++类型的参数,被重复计算
* typeof(x) _min1 = (x);
*/
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
int main ()
{
int ret;
int i = 100;
int j = 200;
ret = min(i++, j++);
printf("ret = %d\n", ret);
return 0;
}
------------------------------------------------------
#include <stdio.h>
/*
* 这种写法,利用了do while的巧妙之处,但是也有最大一个缺憾,无法获得该宏的返回值;
* 如果只想实现一组语句的正确执行,而不关心其返回值,可以使用do while;
* 但是如果想获取这组语句的返回值,则必须使用()和{},将返回值放在最后一句。
*/
#define min(x, y) \
do { \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; \
} while (0)
int main ()
{
min(10, 30);
return 0;
}
------------------------------------------------------
#include <stdio.h>
int main ()
{
int i;
char j;
/*
* 通过下面测试证明,取址操作获取的地址是有类型的
* &i 获取的地址类型为 int *
* &j 获取的地址类型为 char *
*/
printf("&i = %p\n", &i);
printf("&i+1 = %p\n", &i+1);
printf("&j = %p\n", &j);
printf("&j+1 = %p\n", &j+1);
(void)(&i == &j);
return 0;
}
$ gcc test.c
test.c: 在函数‘main’中:
test.c:17: 警告: 比较不相关的指针时缺少类型转换
$ ./a.out
&i = 0xbfeccbac
&i+1 = 0xbfeccbb0
&j = 0xbfeccbb3
&j+1 = 0xbfeccbb4