4

ここ数日から、未定義の動作について学ぼうとしていました。数日前、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 の値は 、これらのステートメントでどこも変更されていないため、以前の値ではなく単なる値です。1iij = i + 1a[i] = i i

2.a[i] = i++またはの場合はa[i++] = i、上記文の最初の文

前のシーケンス ポイントと次のシーケンス ポイントの間で、オブジェクトの格納値は、式の評価によって最大 1 回変更されます。

i getは、連続する 2 つのシーケンス ポイント間で 1 回だけ変更される ため、失敗しました。そのため、2 番目の文が必要です。
これらの例はどちらも C では許可されていません。これは、 の以前の値が i 2 回アクセスされるためです。つまり、i++ それ自体 が式内の の以前の値にアクセスしてそれを変更するためです。したがって、以前の値 / の値への他のアクセスは、変更た値を 決定するためにアクセスされないため不要です。格納する値。 ii

i = i++問題は、c-faq に記載されて いる式を思いついたときに始まります

実は、これまで議論してきた他の表現も 2 番目の文に違反しています。

iこの式では (RHS で) にアクセスして、 の変更された値を決定すると思いますi
この式は 2 番目のステートメントにどのように違反していますか?

4

1 に答える 1