2016-06-11 31 views
1

我得到1249從這個代碼怪異的結果,而使用前遞增和後遞增運營商

#include <stdio.h> 
#define product(a) a*a 

int main() { 
    int i = 3, j, k; 
    j = product(i++); 
    k = product(++i); 
    printf("%d %d\n", j, k); 

    return 0; 
} 

如果不是使用宏您使用的功能,那麼你獲得了9個和25個,其是我所期望的...

有人可以解釋爲什麼會發生這種情況嗎?

+0

該代碼基本上使用宏來部分隱藏重複問題更明確地顯示的未定義行爲。問題是一樣的:序列點之間的'i'雙重增量導致未定義的行爲。 –

+0

@JonathanLeffler其實我從前就知道,在同一句話中使用多個操作符會產生不確定的行爲,我遇到的問題是我不知道宏在做什麼...... – OiciTrap

回答

1

如果展開宏,行

j = product(i++); 

成爲

j = i++*i++; 

和線

k = product(++i); 

成爲

k = ++i*++i; 

這兩行都有未定義的行爲。您可以嘗試理解程序的一次運行情況,但結果不能保證與不同的編譯器或具有不同編譯器標誌的相同編譯器相同。

當您使用函數調用而不是宏時,代碼的行爲更直截了當。行

j = product(i++); 

相當於:

int temp = i; 
j = product(temp); 
i++; 

k = product(++i); 

相當於:

++i; 
k = product(i); 

因此,不存在任何問題時的功能是用來代替宏。

0

您預計會要求你的宏更改爲函數的輸出

#include <stdio.h> 
int product(int a) { return a * a; } 

int main() { 
    int i = 3, j, k; 
    j = product(i++); 
    k = product(++i); 
    printf("%d %d\n", j, k); 

    return 0; 
} 

輸出

9 25 

由於宏觀解包內聯的i變化在main功能的callframe值你會得到意想不到的結果。