2012-01-24 68 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

相關問題