宏的副作用
宏定义在实际使用中如果不稍加注意,如果表达式有副作用,就可能导致返回的结果跟预期不符。下面是几种常见的问题:
输入输出
#define MULTI(a,b) a * b
MULTI(1+2,3);// => 1 + 2 * 3
#define ADD(a,b) (a) + (b)
int c = ADD(1,2) * 3; //1 + 2 * 3
因此宏的参数和返回值最好是用()扩起来
#define MULTI(a,b) ((a) * (b))
#define ADD(a,b) ((a) + (b))
自增自减运算
#define MAX(a,b) ((a) > (b) ? (a) : (b))
int a = 3,b = 2;
int c = MAX(a++,b);
返回值预期是4(a++)实际上是5,a进行了两次++运算。
所以一般使用宏最好不要传入自增自减。
实际使用参数和宏内部变量同名
#define HASH(str, sz, rst) \
do \
{ \
unsigned int n = 0; \
n = xxx; \
rst = n % sz; \
} while (0)
这是一个hash的宏实现,其中定义了一个临时变量n,根据str计算n,然后对sz求模并把返回值赋给传进来的rst.
这么调用:
int n;
HASH("hello",7,n);
不会达到改变n的效果,因为实际使用参数n和宏内部的变量n同名。解决办法是宏内部变量使用一种不同风格的命名方式。
#define HASH(str, sz, rst) \
do \
{ \
unsigned int _n = 0; \
_n = xxx; \
rst = _n % sz; \
} while (0)