如何编写一个优秀的GNU C的宏

本文探讨了在C语言中定义宏来计算两个数最大值的问题,分析了不同宏定义方式的潜在问题,如运算符优先级、副作用和类型安全。通过逐步改进宏定义,展示了如何创建一个更安全、更健壮的解决方案,包括使用括号增强运算符优先级和利用typeof关键字确保类型安全。最后,提到了在宏定义中避免副作用的重要性。
摘要由CSDN通过智能技术生成

题目:定义一个宏,求两个数的最大值。

合格答案

#define MAX(x,y)  x > y ? x : y

当运行如下语句时会出Bug:

printf("MAX=%d",MAX(1!=1,1!=2));

 

中等答案

#define MAX(x,y)    (x) > (y) ? (x) : (y)

当运行如下语句时会出Bug:

printf("MAX=%d",3 + MAX(1,2));

原因:+运算符的优先级大于比较运算符>

良好答案

#define MAX(x,y)    ((x) > (y) ? (x) : (y))

当运行如下语句时会出出现Bug:

printf("MAX=%d",MAX(i++,j++));

原因:宏展开是将参数原样复制展开,导致i自加了两次,所以最好不要在宏里面加可变参数。

优秀答案 

#define MAX(type,x,y)({    \
        type _x = (x);    \
        type _y = (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)的作用:(1) 给用户提示一个警告,对于不同类型的指针比较,编译器会发出一个警告,提示两种数据的类型不同;(2) 运算的结果没有用到,有些编译器可能会给一个warning,加一个(void)后,就可以消除这个警告。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值