宏定义副作用分析
- 副作用情况:在
int result = MAX(x++, y++);
中,由于宏定义 MAX(a, b) ((a) > (b)? (a) : (b))
只是简单的文本替换,会被替换为 ((x++) > (y++)? (x++) : (y++))
。这会导致 x
和 y
可能会被多次自增,结果取决于 x++
和 y++
的比较结果。
- 举例说明:假设初始
x = 5
,y = 10
,(x++) > (y++)
比较时,先使用 x
和 y
的值进行比较(即 5
和 10
),然后 x
和 y
各自自增为 6
和 11
。因为 5 < 10
,所以取 y++
,y
再次自增为 12
。此时 x
自增了一次变为 6
,y
自增了两次变为 12
。
改进方案
- 使用函数替代宏:
int max(int a, int b) {
return a > b? a : b;
}
- 使用宏改进:
#define MAX(a, b) ({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
_a > _b? _a : _b; \
})
改进原理
- 函数替代宏:函数调用时参数只会计算一次,在
int result = max(x++, y++);
中,x++
和 y++
作为参数传递给函数 max
,x
和 y
各自只会自增一次,避免了宏定义中多次自增的副作用。
- 宏改进:使用
typeof
来获取变量类型,创建临时变量 _a
和 _b
来存储 a
和 b
的值。这样在比较和返回结果时使用的是临时变量,原变量 a
和 b
不会被多次操作,避免了副作用。例如在 int result = MAX(x++, y++);
中,x
和 y
各自只会自增一次。