宏观扩张的奇怪行为

时间:2013-03-11 11:14:09

标签: c macros c-preprocessor

以下是代码:

#include <stdio.h>
#include <stdio.h>
#define VAL1(a,b)    a*b
#define VAL2(a,b)    a/b
#define VAL3(a,b)    ++a%b
int main()
{
    int a = 1;
    int b = 2;
    int c = 3;
    int d = 3;
    int e = 5;

    int result = VAL2(a,d)/VAL1(e,b)+VAL3(c,d);  // result = 1
    //int result = a/d/e*b+++c%d;                // result = 0

    printf("%d\n", result);

    return 0;
}

为什么两个陈述的结果不相同?

3 个答案:

答案 0 :(得分:7)

在一个案例中,您有+ ++,而在另一个案例中,您有++ ++ ++++ +令牌的不同流。宏粘贴不会改变标记化,因为它是粘贴的标记。

如果您将程序打入C预处理器,那么您将获得该行:

int result = a/d/e*b+ ++c%d;

请注意,预处理器必须插入空格,因为+令牌和++令牌之间必须有空格。

答案 1 :(得分:0)

我尝试用GCC 4.7编译它,两个表达式给出了相同的结果。

如果你想看宏如何扩展,你可以使用cpp,这是C预处理器,并在执行预处理器表达式后给你输出,这里的输出是

int main()
{
    int a = 1;
    int b = 2;
    int c = 3;
    int d = 3;
    int e = 5;

    int result = a/d/e*b+++c%d;  
    int result2 = a/d/e*b+++c%d;  

    printf("%d %d\n", result, result2);

    return 0;
}

答案 2 :(得分:-1)

如果您确实认为有必要使用此类宏,则需要使用括号()来避免副作用:

#define VAL1(a,b)    ((a)*(b))
#define VAL2(a,b)    ((a)/(b))
#define VAL3(a,b)    ((++a)%(b))