C語言自加問題
2015/10/14 13:44
瀏覽285
迴響0
推薦0
引用0
看見有個面試題目,求x, y的值:
int i = 3, j = 3;
int x = (++i) + (++i) + (++i);
int y = (j++) + (j++) + (j++);
看到挺多人在爭論,這樣的表達式值應該是多少?甚至拿出幾個不同的編譯器來編譯運行得到幾個不同的結果。對於此題的答案,一句話,The behavior is undefined! 詳細解釋待我慢慢說來。
大家知道,通常而言,我們寫的計算機程序都是從上到下,從左到右依次執行。然而,我只是說通常,因為在編譯的過程中,compiler並不僅僅是把 source code翻譯成binary code就算了,這個過程裏面可能還會對代碼進行優化,這種優化可能帶來的結果是:代碼或者表達式evaluation的順序可能發生變化。這可是一個非 常嚴重的問題,當某個表達式帶有side-effect(比如改變了一個變量的值),那麽它的執行順序直接影響到了程序執行的結果。
為了保證程序執行具有確定性的結果,C++標準引入Sequence Point這個概念,按照ISO/IEC的定義:
At certain specified points in the execution sequence called sequence points. All side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place.
簡而言之,Sequence Point就是這麽一個位置,在它之前所有的side effect已經發生,在它之後的所有side effect仍未開始,而兩個Sequence Point之間所有的表達式或者代碼執行的順序是未定義的!
而C++標準又進一步規定了Sequence Point出現的5種情況:
At the end of a full expression
After the evaluation of all function arguments in a function call and before execution of any expressions in the function body
After copying of a returned value and before execution of any expressions outside the function
After evaluation of the first expression in a&&b, a||b, a?b:c, or a,b
After the initialization of each base and member in the constructor initialization list
具體我不詳細討論,只看第一個情況:At the end of a full expression,這裏簡化問題,full expression簡單認為是一個帶有;的語句(具體可以再去查標準)。也就是說,任何一個獨立的表達式語句的結束都是一個Sequence Point,回到我們的題目:
int y = (++i) + (++i) + (++i);
整個的語句裏面,只有1個Sequence Point,也就是語句的結束點,對於右邊表達式的計算順序沒有任何的規定,顯然,各種編譯器都可以按照他們覺得“舒服”的方式來進行計算,這樣的代碼, 如果只要求在特定的平臺或者編譯器運行,那麽帶來的可能只是可讀性差的問題,但如果考慮跨平臺或者編譯器的情況,那麽就是完完全全的錯誤!
另外,需要特別註意的是,對於賦值號(assignment operator),C++也沒有把它定義成Sequence Point,也就說這樣的語句:
buffer = i++;
同樣是undefined的,因為,對於等號左右兩邊的表達式運算順序,你並不能有任何的假定。
你可能會有興趣的文章:
限會員,要發表迴響,請先登入


