Linux-C 最正确的取最大最小值宏

【版权申明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) 

Linux-C 最正确的取最大最小值宏

这里以两个值中取最小值为例:
#define min_t(type, x, y) \
({ type __x=x; type __y=y; __x<__y? __x:__y })

GNU C把包含在括号中的复合语句看成是一个表达式, 称为语句表达式, 它可以出现在任何允许表达式的地方. 我们可以在语句表达式中使用原本只能在复合语句中使用的循环、局部变量等, 例如:

#define min_t(type, x, y) \
({ type __x=x; type __y=y; __x<__y? __x:__y })

int ia, ib, mini;
float fa, fb, minf;

mini = min_t(int, ia, ib);
minf = min_t(float, fa, fb);

因为重新定义了__x和__y这两个局部变量, 所以用上述方式定义的宏将不会有副作用. 在标准C中, 对应的如下宏则会产生副作用:

#define min(x, y) ((x)<(y) ? (x) : (y)) 

在很长一段时间内我都觉得这是最正确的, 毕竟它加上了括号, 排除了x或y是一个表达式导致了错误的可能. 万万没想到当x或y是x++或者y++时它的异常情况…

代码min(++ia, ++ib)会展开为((++ia) < (++ib) ? (++ia) : (++ib)), 传入的宏的"参数"
增加了两次!

在这里我假设你在写笔试题, 然后笔试题又限制宏只能使用两个参数或者说x,y不是同一个类型的:
此时我们可以巧用typeof关键字:
#define min(x, y) ({		\
const typeof(x) __x = (x);	\
const typeof(y) __y = (y);	\
(void) (&__x == &__y);		\
__x < __y ? __x : __y; })

我们不需要像min_t(type, x, y)那个宏那样把type传入, 因为通过typeof(x)、typeof(y)可以获得type.

代码行(void)(&__x == &__y)的作用是检查__x和__y的类型是否一致.指针(地址)的比较也需要相同类型, 不同的话编译器会警告!

以上内容大部分摘抄自《Linux设备驱动开发详解 基于最新的Linux4.0内核》宋宝华
第三章 Linux内核及内核编程

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安河桥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值