前幾天我看到了關於c語言中i+++i+++i++的問題討論。有認爲值是肯定的,也有認爲是不肯定的。我原本傾向於肯定的,即well-defined。原本想NB一把,我們翻標準準確說明它就是well-defined,結果卻發現它是undefined。這不,一想那不是更厲害了,直接把前面認爲肯定的人都否認了。立即組織材料,本身也寫個回覆。寫的出來後那是至關的有成就感啊,就等着別人來討論討論。可是我更渴望別人也以爲我觀點是對,知足一下本身這顆虛榮心,^_^。不過好傷心啊,沒人回覆。 html
不過話說回來啊,這個過程挺有趣的。先是本身帶着觀點去找證據,結果發現觀點錯了,又找證據證實另外一個觀點,最後把一點一點碎片組織起來,就成一篇小文章了。我想啊,那些發表論文的,當寫完審查完那一刻確定是至關知足了。開始先是一個一個的lemma, 而後是corollary, 最後就是本身的theorem了。忽然感受寫程序的過程也很像。先是小函數,小函數組成大一點的函數,慢慢的本身的程序也就浮現出來。其實,還有不少過程都很像,不是嗎?
express
好了,在這就再貼下本身的回答,保存下,也再成就感一下。若是有錯誤,麻煩你們給指出啦。
數組
標準中提到tranlation有7個階段,下面是第3階段的描述(c99 5.1.1.2) 函數
The source file is decomposed into preprocessing tokens and sequences of white-space characters(including comments).這個階段先於第4階段的預處理髮生。在preprocessing tokens的定義裏面包括punctuator。而punctuator裏面包括operator。因此根據下面的這兩段話(c99 6.4):
If the input stream has been parsed into preprocessing tokens up to a given character, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token.
EXAMPLE 2 The program fragment x+++++y is parsed as x ++ ++ + y我頗有理由認爲i+++j 這個表達式確定是分析成i ++ + j。而這些只是preprocessing tokens,在translation的第7階段才把這些轉換成標準中定義的tokens,而後再進行語法的分析。tokens已經被分紅那樣了,根據優先級,應該是(i++) + y。因此,我認爲 i+++i+++i++ 在語法上是被分析爲(i++)+(i++)+(i++)。
下面是說明這個式子是undefined的。其實標準裏面讓它undefined的說明關鍵就一個了(c99 6.5): post
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.這裏的第一句話就讓式子undefined的了。對於sequence point,標準裏的定義是informative(不懂啥含義)的,其中包括the end of a full expression,而full expression定義以下(c99 6.8)
A full expression is an expression that is not part of another expression or of a declarator.
因此,上訴式子是「Between the previous and next sequence point「無誤了。並且標準中還給了兩個因爲6.5那段而undefined的例子: lua
i = ++i + 1; a[i++] = i;
因此,個人結論是式子i+++i+++i++只能被分析成(i++)+(i++)+(i++),但結果是undefined。 spa
ps:對於6.5那段的第二句我不是太理解,參考了一下別人的說法暫時理解爲:若是兩個sequence points之間要改變一個object所存的值,那麼以前若是有讀取此object的值,那麼這個以前讀的舊值一定是用來肯定新值的。 orm
不知道理解正與否。 htm
參考: token
ISO標準
http://stackoverflow.com/questions/3978625/using-postfix-increment-in-an-l-value
http://c-faq.com/expr/seqpoints.html