规则5.1 用宏定义表达式时,要使用完备的括号
#define RECTANGLE_AREA(a,b) ((a)*(b))
规则5.2将宏定义的多条表达式放在大括号中
说明:更好的方法是多条语句写成do while(0)的方式。
示例:
#define F00(x) do{
printf("arg is %s\n",x);
do_something_useful(x);
}while(0)
规则5.3使用宏时,不允许参数发生变化
示例:如下用法可能导致错误
#define SQUARE(a) ((a)*(a))
int a=5;
int b;
b=SQUARE(a++);
正确的用法是:
b=SQUARE(a);
a++;
同时也建议即使函数调用,也不要在参数做变量的变化操作,因为可能引用的接口函数,在某个版本升级后,变成了一个兼容老版本所作的一个宏,结果可能不可预知。
规则5.4 不允许直接使用魔鬼数字
建议5.1 除非必要,应经可能使用函数替代宏
建议5.2 常量建议使用const定义替代宏
说明:“尽量用编译器而不用预处理”,因为#define经常被认为好像不是语言本身的一部分
语句:
#define ASPECT_RATT0,1.653
编译器会永远看不到ASPECT_RATIO这个符号名,因为在源码进入编译器之前,它会被预处理程序去掉,于是ASPECT_RATIO不会加入到符号列表中,如果涉及这个常量的代码会在编译时报错,就会很让人费解,因为报错信息指的是1.653,而不是ASPECT_RATIO。如果这个不是在你头文件定义的,你就会奇怪他到底是哪里来的,甚至会花时间跟踪下去,这个问题也会出现在符号调试器中。
解决这个问题的方法是定义一个常量
const double ASPECT_RATIO=1.653;
建议5.3 宏定义中尽量不使用return,goto,continue,break等改变程序流程的语句
说明:如果在宏定义中使用这些改变流程的语句,很容易引起资源泄露问题,使用者很难自己察觉