#define MIN(A,B) (A)<(B) ? (A) :(B);bool aa = 3 < MIN(2,3);
#define MIN(A,B) ((A)<(B) ? (A) :(B));bool bb = 3 < MIN(2,3);
上面代码本身的意图是,将3与2,3的较小者进行大小比较。aa,bb的期望的值应该是false。但是上面代码的结果却并非如此(真实情况:aa=true,bb=false)。注意第一段代码与第二段代码的区别在于,第二段代码将整个宏用括号括起来了,作为一个整体,而第一个则没有。
到底是为什么呢?我们将宏直接替换的规则,代码被替换如下:
[1] bool aa = 3 < 2 < 3 ? 2:3;[2] bool bb = 3 < (2<3?2:3);
显然bb与正常想法一致,很好理解。[1]中,根据小于号的左结合原则,先计算3<2 结果为false(被当作0)再参与接下来的计算即,
aa = 0<3?2:3;
结果为2,被转换为bool型时,aa=true。这就是原因所在,如果将aa的类型改变为int,可以发现aa的最终值为2。足以证明分析结果。
p.s:这个问题是在刷POJ过程中定义了宏被WA掉后发现的,所以在使用宏的时候特别要注意其所带来的副作用。