3

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

x = x = 5;

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

私が実際に出くわしたのは(より大きな表現で)

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

しかし、私はそれが警告にとって重要であるとは思いませんでした(それが問題の核心であると私が想定したものではなく、それが要点である場合は私を訂正してください)。

4

1 に答える 1

5

x組み込み型であると仮定するとx、シーケンスポイントを介さずに2回割り当てられます。これは、知っておく必要があるすべてです。両方の割り当てが同じ値(5)であり、理論的には単一の割り当てに最適化できるという事実(x揮発性でない場合)は、ここにもそこにもありません。

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

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

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

アブルンキーの言うことは正しい。2つのステートメントを使用できない状況にある場合は、x[0][0] = 5, x[0][i] = 5代わりに記述してください。どちらの場合も、冗長な割り当てを破棄するだけです。

于 2010-11-09T00:18:10.553 に答える