關於c前置,後置++,及函數傳參的問題?
如下一段代碼:
#include &
int funadd (int a, int b) {
return 2 * a + 3 * b;
}
int main()
{
int index = 1;
int c = funadd(++index, ++index);
printf("%d
", c);index = 1;
c = funadd(index++, index++);
printf("%d
", c);index = 1;
c = funadd(index++, index);
printf("%d
", c);index = 1;
c = funadd(index, index++);
printf("%d
", c);scanf("%d", c);
}
輸出:
使用GCC以及VS2015自帶編譯器的輸出皆為:
15
7
8
7
按照我的理解,第一個調用相當於funadd(2, 3)=13,第二個相當於funadd(1, 2)=8,第三個相當於funadd(1, 2)=8,第三個相當於funadd(1, 1) = 5.
實際的輸出是否是由於指令重拍以及傳參順序等引起的?
/*******補充**********/
其實問題來源於工作中我寫的一段與此類似的代碼,發現有問題之後才做的這些測試,代碼類似如下:
class TestClass {
public:
int x;
int y;
TestClass(int a, int b) {
x = a;
y = b;
}
void getvalue() {
cout &<&< "[" &<&< x &<&< " " &<&< y &<&< "]" &<&< endl;
}
};
int main()
{
int *data = (int *)malloc(sizeof(int) * 6);
for (int i = 0; i &< 6; ++i)
{
*data++ = i;
}
data -= 6;
vector&
veccc; for (int i = 0; i &< 3; ++i)
{
TestClass tc(*data++, *data++);
tc.getvalue();
}
free(data-6);
}
其輸出為:
[1 0]
[3 2]
[5 4]
我期望的輸出為:[0 1] [2 3] [4 5]。
我做了一些測試,有如下規律:如果是兩個前置++,那麼就好像兩個++操作都會被「重排」到傳參之前,即傳入的是(index+2, index+2);如果是兩個後置++操作,那麼第二個參數就會優先處理,而第一個參數則是因為++的作用而加1,相當於傳入的是(index+1, index)。
我不懂彙編,是否能有大大有空幫忙看看彙編是啥情況,感激不盡!
具體到這個例子,兩個參數的求職順序可以先左後右或者先右後左,後置++可以在index++求值到遇到分號之間的任何時候執行,所以不同的編譯器、同一個編譯器的不同配置(如debug和release)、還有跟人腦有不同的結果是正常的。
未定義行為。
理論上來講,編譯器可以把代碼編譯成在此時故意立即格式化你的硬碟,也是符合語言標準的。
建議你不要依賴或過度考慮參數求值順序。
C 和 C++17 前的函數參數求值是無序 (unsequenced) 的。上面代碼涉及到對標量對象的無序的兩次寫入或無序的讀和寫,產生未定義行為(允許崩潰)。而 C++17 起函數參數求值變為不確定順序 (indeterminately sequenced) ,使用哪種順序是未指定的。儘管上面這些代碼在 C++17 中合法,但仍然有不可預測的行為,包括不同位置的行為可以不同。推薦閱讀:
※已經不在學校了,在軟體專業上,該怎麼制定學習的策略?
※國內哪一家公司的編譯隊伍技術最高?
※typeid如何得出變數的類型?
※最好的編譯器課程
※動手寫一門簡單語言吧喵 從計算姬開始