ISO/IEC 9899(TC2)§6.5 - 2式が教えてくれる:なぜprintf( "%d%d%d"、++ i、i、i ++)は未定義の動作ですか?
以前と次のシーケンスポイント間でオブジェクトが格納された値は、式の評価によって、最高1回に変更なければなりません。さらに、以前の値は、格納される値を決定するためにのみ読み出されるものとする。
これは私が心に留めていたことであり、タイトルからの行が予期せぬ出力を与える理由を誰にも尋ねたと思います。
は、しかし、今日、私はちょうどこのライン発見:
§7.19.6 - 1書式付き入力/出力機能:
をシーケンスポイントの後があるかのようにフォーマットされた入力/出力機能を振る舞うもの各指定子に関連付けられたアクション。
私が想定し作られたどの:
int i = 0;
printf ("%d, %d", ++i, i++);
は未定義である必要がありますが、次の例では、言及した句で[OK]をする必要があり:
int i = 0;
printf ("%d, %d, %d", ++i, i, i++);
しかし、出力は次のようになります。
2, 2, 0
これは未定義の動作を示す良い例ではありませんでした。
なぜですか? 句がtrueの場合
「[...]各指定子に関連付けられたアクションの後にシーケンスポイントがあるかのように振る舞います。」
(関連配列点を表すSP)
: - 次に§6.5下ルール適用
指定子に関連付けられたactiosnの各々に2は、私たちは同様にそのルールを交差させません
SP ++i
SP i
SP i++
前のSPと次のSPの間の指定された範囲のSP1から、++i
はi
の格納値の唯一の変更です。
SP2からは、前のSPと次のSPの間の範囲は、++i
とi
です。++i
は、この値の唯一の変更です。私たちは今、SP3を取る場合
前のSP(SP2)、次のSP(呼び出しの終わり)との間で起こっていることすべてがある:
i
、全体でi
のi++
まだ1つだけ修正前のSPと次のSPの間の範囲。
ここで私はシーケンスポイントの仕方について間違って解釈していますか?
あなたがそれが適切であると思うならば、それを下降させてください。しかし、これは単なる別の問題ではないことに注意してください。私は私には奇妙に見える何かに遭遇した、私はそれについてのまともな研究を静かにし、私の混乱の明確なポイントを作った、なぜこれは他の質問とは異なるです。あなたがまだ何かを見逃していると思ったり、十分な努力をしなかったと思ったら、どうしてそう思うかを少なくとも私に教えてください。 – dhein