3


0

未定義の動作または誤検知

私は(本質的に)野生で次のものに出会いました

x = x = 5;

gccの以前のバージョンではきれいにコンパイルされているようです(gcc 4.5.1では警告が生成されます)。 私が知る限り、警告は-Wsequence-pointによって生成されます。 だから私の質問は、これがシーケンスポイント間で変数を操作することに関する標準の文言に違反するか(つまり、仕様ごとに未定義の動作です)、これはgccの誤検知です(つまり、仕様ごとに定義された動作です)? シーケンスポイントの文言を理解するのは少し難しいです。

私が実際に出会ったのは(より大きな表現で)

x[0][0] = x[0][0] = 5;

しかし、私はそれが警告にとって重要であるとは思いませんでした(それがポイントであり、問​​題の核心であると仮定したものではない場合、私を修正してください)。

1 Answer


5


x`が組み込み型であると仮定すると、介在するシーケンスポイントなしで x`に2回割り当てられます。 両方の割り当てが同じ値(5)であり、理論上は単一の割り当てに最適化できるという事実(「x」が揮発性でない場合)は、ここにもそこにもありません。

少なくとも、それは標準で「変更」を解釈する方法です-古い値と同じかどうかに関係なく、値を割り当てました。 同様に、constをキャストしてconstオブジェクトに割り当てることは、割り当てる値が前の値と等しいかどうかに関係なく、UBであると思います。 そうしないと、実装が文字列リテラルをROMに入れて、その場合のページフォールトを防ぐ必要がある場合、すべてのメモリ書き込みに大きなオーバーヘッドがあり、コンパイラがそのコードを出力しないことがわかります。

さらにエキサイティングな例は x [0] [0] = x [0] [i] = 5;`です。これは、 `i == 0の場合にのみ、介在するシーケンスポイントなしで同じオブジェクトに割り当てます。 `、 i`の値を条件に定義された動作です。

どちらの場合でもコンパイラが予期しないことをする理由はわかりませんが、想像力の欠如は無関係です:-)

ABLENKYの言うことは正しい。 2つのステートメントを使用できないコンテキストにいる場合は、代わりに `x [0] [0] = 5、x [0] [i] = 5`と書きます。 どちらの場合も、冗長な割り当てを捨ててください。