1. 問題描述
以下代碼的輸出結果是什么?
題目1:
int i=10; printf("%d, %d\n", i++, ++i);
題目2:
int i = 3; printf("%d, %d, %d, %d, %d\n", i++, ++i, i, i++, i);
2. 解題思路【錯誤】
printf參數是從右至左入棧的,故:
- 題目1的輸出為:11,12
- 題目2的輸出為:
3. 反思
- 注意:該類題目編譯器不一樣,結果就會不一樣,即這種行為依賴編譯器!!!不必糾結。
- 原因分析:
- C/C++語言沒有規定具體壓棧順序,沒有標准化時C語言支持沒有固定參數的函數,所以為了實現這個當時多數編譯器都采用從右往左壓棧,但是標准化的要求至少有一個固定參數,這個限制就沒有必要了。不過從右到左幾乎已經成為了C編譯器慣用的順序。C++的_stdcall方式也是采用從右到左,不同的只是不需要調用者自己手動清棧。
- 另外求值順序和壓棧順序是兩回事,C語言里幾乎沒有對求值順序做規定,編譯器完全可以先求出值再決定如何壓棧。
- 簡單說,這種問題與編譯器實現語言的規定有關。不同編譯器下生成的代碼可能不同,出現的結果就不同。對於這種可能造成錯誤的代碼,不用糾結。
What's the value of i++ + i++?
It's undefined. Basically, in C and C++, if you read a variable twice in an expression where you also write it, the result is undefined. Don't do that. Another example is:
v[i] = i++;
Related example:
f(v[i],i++);
Here, the result is undefined because the order of evaluation of function arguments are undefined.
Having the order of evaluation undefined is claimed to yield better performing code. Compilers could warn about such examples, which are typically subtle bugs (or potential subtle bugs). I'm disappointed that after decades, most compilers still don't warn, leaving that job to specialized, separate, and underused tools.