语言陷阱:C/C++的宏替换

C/C++的宏非常不错,非常强大,我自己用的也非常顺手。自己的代码刚开始写的时候其实到处都是宏,然后根据需要,切换为C++,切换为Java,一会排成一字,一会排成人字。但使用却必须要小心些了,比如下面的语句:

       #define abs(x) (x)<0?0-(x):(x)
       #define rand(x) abs(rand()%x)
       

本来的意愿是调用rand(x)获取一个[0~x)范围的随机数。但抱歉的是,上述代码并不能保证你获得的是想要的,很有可能还是会产生负数,原因在于当编译器处理宏的时候,会变成这样:

       (rand()%x)<0?0-(rand()%x):(rand()%x)
       

看到了吧,如果第一个rand产生一个负数,而第二个rand产生一个正数或者第一个产生正数或零,第三个产生负数,结果都为负数。调整的方法有两个,一个是将abs封装成函数,或者在宏中间添加个临时保存的变量。

如果没记错的话,某本书或者某篇文章提到过这个问题。有些老调重弹了。

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据