#defines ... do{ ... } while(0)?

为什么复杂的宏定义中常见#defines ... do{ ... } while(0)而非#defines ... { ... }

其实大家应该都明白#define SQUARE(x) ((x)*(x))为什么要加括号,就是防止宏替换时候函数不按自己的想法执行,用{}也是想做好封装,其实还是有风险的。

看一个例子就明白了

#define Max(a,b) { (a)>(b)?(a):(b);}
if(1)
Max(2,3);
else
Max(4,5);

看出问题了没,这个函数编译会报错error C2181: illegal else without matching if,是说else没有对应的if,这怎么可能呢?前面明明有if啊!!!仔细分析会发现平时写if-else语句无非两种格式

if()
func1;
else
func2;

或者

if()
{
   func1;
}else
{
   func2;
}

但上面的Max不是函数,是宏,被替换后就会变成

if()
{
   func1;
};else
{
   func2;
}

多出的分号;就把if给截断了,if单独成判断语句和else分家了。所以有前面报错。
进行下面修改

#define Max(a,b) do { (a)>(b)?(a):(b);}while(0)
if(1)
Max(2,3);
else
Max(4,5);

用do-while(0)方式定义宏,完全不用担心使用者如何使用宏,也不用给使用者加什么约束。

P.S.能用函数代替的尽量不要用宏,原因如下:

  • 宏使用不当会有意外的副作用,上面便是
  • 大量的宏替换占用大量代码空间,不如函数效率高
  • debug调试宏内部无法设置断点,不利于问题定位
  • 宏缺乏类型检查,不如函数语法检查严格
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值