2012-01-24 33 views
-3

我写了一个C程序,然后在MS Visual Studio中编译并运行它,然后使用GCC。该程序进行了一些简单的数学计算。但是我从两者得到的输出/结果是不同的。该程序基于宏。不同的结果使用MS Visual Studio vs 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值。所以我想知道不同的编译器是否以不同的方式处理宏的过程?

+10

向我们展示一些代码。你可能有某种未定义的行为,例如'x = x ++ + ++ x;' – Mysticial

+5

结果有多不同?如果有人说“3.14159266666666”,而另一个说“3.14159266666667”,你应该阅读[“每个计算机科学家应该了解的浮点数”](http://docs.oracle.com/cd/E19957-01/806-3568/ ncg_goldberg.html)。 – pmg

+3

试图直接回答你的问题:他们尽量不要。 –

回答

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 

,因此不会正确评估。

尝试使用-E选项来gcc检查宏的预处理器输出是否有疑问(即,在标题和宏已扩展但在编译之前)。它会产生大量的文本,但是你将能够发现你的宏观扩展到底部。例如:

gcc -E file.c -o file.txt 
+0

非常感谢您的详细解答。 – aclark

相关问题