使用MS Visual Studio与GCC的结果不同

时间:2012-01-24 18:14:43

标签: c visual-studio-2008 gcc

我编写了一个C程序,然后在MS Visual Studio中编译并运行它,然后使用GCC。该程序进行了一些简单的数学计算。但是我从两者得到的输出/结果是不同的。该程序基于宏。

这些编程环境是否有不同的处理宏的方式?如果是这样,有什么区别?

编辑:对不起,这是代码。

#include <stdio.h>
#define mac(a,b) a*a + b*b - 2*a*b

int func(int a, int b) {
    return (a*a + b*b - 2*a*b);
}
main() {
    int f, g, i, j, x, y;
    printf("Please enter two integers\n");
    scanf("%d%d", &f, &g);
    printf("f = %d\tg = %d\n", f, g);
    i = f;
    j = g;
    x = func(i, j);
    y = mac(i, j);
    printf("x = %d\ty = %d\n", x, y);
    x = func(++i, ++j);
    i = f;
    j = g;
    y = mac(++i, ++j);
    printf("i = %d\tj = %d\n", i, j);
    printf("x = %d\ty = %d\n", x, y);
}

这是使用VS的输出:

f = 7       g = 8 
x = 1     y = 1 
i = 10    j = 11 
x = 1   y = 1

使用GCC:

f = 7   g = 8 
x = 1   y = 1 
i = 10 j = 11 
x = 1  y = -39

差异是最后的y值。所以我想知道不同的编译器是否会以不同的方式完成宏的过程?

1 个答案:

答案 0 :(得分:5)

y = mac(++i, ++j);

扩展为

y = (++i * ++i) + (++j * ++j) - (2 * ++i * ++j)

这真的是你的想法吗?我想你想要评估(a - b)的平方,所以你应该使用:

++i; 
++y;
y = mac(i,j)

您的问题是评估顺序与编译器有关。您永远不应该使用具有副作用的参数(如++)调用宏,因为它们可能(如您的情况)多次评估。另外你的宏应该用更多括号编写,至少这样:

#define mac(a,b) (a)*(a) + (b)*(b) - 2*(a)*(b)

可以保护您免受

之类的调用
y = mac(i+1, j+1);

在您的示例中将扩展为

y = i+1*i+1 + j+1*j+1 - 2*i+1*j+1

因此无法正确评估。

如果有疑问,请尝试使用gcc的-E选项来检查宏的预处理器输出(即在扩展标头和宏之后但在编译之前)。它会生成大量的文本,但是你可以找到你的宏扩展到底部。例如:

gcc -E file.c -o file.txt