宏中参数的意外多重评估

时间:2014-09-03 05:24:02

标签: c macros

为什么第二个printf的输出是:最大50和67是62?为什么不是50和62的最大值是57?

#define MAX(a,b) ((a)>(b) ? (a): (b))
int incr(){
    static int i =42;
    i += 5;
    return i;
}
int _tmain(int argc, _TCHAR* argv[])
{   
    int x = 50;
    printf("max of %d and %d is %d\n",x, incr(), MAX(x, incr()));
    printf("max of %d and %d is %d",x, incr(), MAX(x, incr()));
    return 0;
}

1 个答案:

答案 0 :(得分:5)

printf("max of %d and %d is %d\n",x, incr(), MAX(x, incr()));

宏替换后,它变为:

printf("max of %d and %d is %d\n",x, incr(), ((x)>(incr()) ? (x): (incr())));
//                                    ^1            ^2               ^3
在此单个函数调用中多次调用

incr(),未指定首先计算哪个参数。无论第一个还是第二个被调用,都会使结果出乎意料。

唯一可以肯定的是由于?:的短路,(x)>(incr()被评估以确定表达式的值是(x)还是第三个的值incr()