ここ数日から、未定義の動作について学ぼうとしていました。数日前、c-faqリンクを見つけました。これは多くの混乱を解消するのに大いに役立ちますが、質問#3.8を読んだときに別の大きな混乱を引き起こします。声明(特に2番目の文)を理解するために多くの努力をした後;
規格は次のように述べています
前のシーケンス ポイントと次のシーケンス ポイントの間で、オブジェクトの格納値は、式の評価によって最大 1 回変更されます。さらに、保存する値を決定するためにのみ、前の値にアクセスする必要があります。
SOでこの質問をしたほうがいいと感じましたが、この声明の2番目の文を説明する答えはありませんでした。最後に、この点について説明を受けました。それとFAQを何度も読んだ後、私は次のように結論付けました。
1.最後の一文
さらに、保存する値を決定するためにのみ、前の値にアクセスする必要があります。
このようになります。
さらに、オブジェクトの以前の値は、格納される(同じオブジェクトの)変更された/新しい値 を決定するためにのみアクセスされます。
例によって明らかなように
int i = 1, j, a[5];
i = i + 1;
j = i + 1;
a[i] = i;
式の場合、 (ここにある) of (RHS)のi = i + 1
前の値にアクセスして、格納する値を決定します。 との場合、アクセスされた i の値は 、これらのステートメントでどこも変更されていないため、以前の値ではなく単なる値です。1
i
i
j = i + 1
a[i] = i
i
2.a[i] = i++
またはの場合はa[i++] = i
、上記文の最初の文
前のシーケンス ポイントと次のシーケンス ポイントの間で、オブジェクトの格納値は、式の評価によって最大 1 回変更されます。
i
getは、連続する 2 つのシーケンス ポイント間で 1 回だけ変更される ため、失敗しました。そのため、2 番目の文が必要です。
これらの例はどちらも C では許可されていません。これは、 の以前の値が i
2 回アクセスされるためです。つまり、i++
それ自体 が式内の の以前の値にアクセスしてそれを変更するためです。したがって、以前の値 / の値への他のアクセスは、変更さ れた値を 決定するためにアクセスされないため不要です。格納する値。 i
i
i = i++
問題は、c-faq に記載されて いる式を思いついたときに始まります
実は、これまで議論してきた他の表現も 2 番目の文に違反しています。
i
この式では (RHS で) にアクセスして、 の変更された値を決定すると思いますi
。
この式は 2 番目のステートメントにどのように違反していますか?