2015-10-09 20 views
5

副作用、シーケンスポイントと未定義の動作

n = ((i++) > (j)?(i++):(j)); 

本はI> Jを推定することを主張し、nは予期しない値を持っており、私は二回インクリメントされます。
この文の後にnが期待値を持つ理由はわかりません。
は、私は(存在しないので、いない書籍の説明)ので、ここ理論だ、未定義の動作についての多くの例を読んで、私が正しいかどうかを教えてください:

まず、(私は++します)>( j)が評価され、iがインクリメントされている場合とされていない場合があります。 です。
i> nと仮定すると、(i ++)を評価する必要があります。 私はまだインクリメントされているかどうかはなので、この理由のため ステートメントは定義されていません。 iまたはi + 1が返されるかどうかはわかりません。

は今ここに私の理論を推定問題は右である - は、なぜ我々は、私はまだかインクリメントされているかどうかを を知らないのですか?このコード行がif文として記述されていた場合、前にインクリメントする必要があると私は確信しています。ではなぜ化合物が違うのですか?

ありがとうございます。

+2

あなたはすでにあなたの質問に答えています。シーケンスポイントについて読む。 – Olaf

+0

@ WumpusQ.Wumbley:ありがとう、CVが取り下げられました。 – Olaf

+0

"なぜ化合物は違うのですか?"それは...ですか? http://port70.net/~nsz/c/c11/n1570.html#6.5.15p4 – Olaf

答えて

5

演算子?:にはシーケンスポイントが導入されているため、ここでは未定義の動作はありません。

(i++) > (j)は、と評価され、副作用は、i++となり、となります。 (i++) > (j)の結果が真であれば、(i++)が再び評価され、そうでなければ(j)が再び評価される。

i++iの前には、の値が加算されます。だから、i > jと仮定すると、次の

n = i++ > j ? i++ : j; 

を評価した後、真でなければなりません:

n = iorig + 1 
i = iorig + 2 

編集

Chapter and verse

6.5.15条件演算子
...
4第1オペランドが評価されます。 第2オペランドまたは第3オペランド(評価された方)の評価と評価の間には、シーケンスポイントがあります。第2オペランド は、最初のオペランドが0と等しくない場合にのみ評価されます。第3オペランドは、 の最初のオペランドが0に等しい場合にのみ評価されます。結果は第2または第3オペランド (評価された方の値)の値となり、以下に説明する型に変換されます。 110)
110)条件式は左辺値を生成しません。
+0

@JeffY:6.5.15/4: "第1オペランドが評価される; *第2オペランドまたは第3オペランド*(評価された方)の評価と評価の間にシーケンスポイントがある。 –

+0

正しい。混乱を避けるためにオリジナルを削除しました。 –

+0

@JohnBodeうわー、私は(あなたが興味があればCプログラミング、現代的なアプローチ第2版、p.323)は、すべてのちょうどブック間違っを証明したと思います。おそらく、第1オペランドの後のこのシーケンスポイントは、C99や何か新しいものであり、この本は古いC89もカバーしています。とにかく、どうもありがとう! –