1

以下は私のコードです

const int i = 10;
cout<<i<<"\n";
int *ip = (int*)&i;
*ip = 20;
cout<<i<<"\n";

10ととしての出力を期待していまし20た。
しかし、私はととして出力を取得してい10ます10

プログラムをコンパイルできますが、コンパイル時または実行時にエラーは発生しませんが、期待どおりの結果は得られません。変数の恒常性を削除した場合、なぜ新しい値が割り当てられないのですか?

誰かが何が起こっているのか、そして私の期待した結果を達成するために何ができるのかを誰かが説明できれば幸いです。

4

1 に答える 1

13

C ++で変数の定数を変更するにはどうすればよいですか?

const本質的に修飾された変数の定数を決して変更しないでください!
修飾変数は、const初期化後に変更しないことを目的として宣言されています。定数を変更しようとすると、コンパイラとの契約が破られます。

変数を変更する必要がある場合は、単にそれをとして宣言しないでくださいconst

C ++はconst_cast、変数の定数を削除または追加するために提供されていることに注意してください。ただし、constnessを削除するときは、元々一定ではなかったものへの参照/ポインターからconstnessを削除するために使用する必要があります。


何が起こっている?

何が起こっているのかは未定義動作です。

修飾変数の定数を変更するべきではありませんconst。ポインタハッカーを介して変更すると、未定義動作が発生します。

未定義の動作の場合、標準はコンパイラにコンパイル時の診断を提供することを義務付けていません。ただし、最高の警告レベルでコンパイルすると、一部のコンパイラが警告する場合があることに注意してください。

また、未定義の動作は、プログラムを実行すると何かが発生する可能性があり、コンパイラが結果を表示する可能性があり、説明が必要ないことを意味します。


なぜ結果なのか?

この場合、定数であるため、おそらくコンパイラは最適化の一部としてconst変数をインライン化します。したがって、ポインタハッカリーは、コンパイラによってすでにインライン化されているため、コード内で検出された場所にインライン化された値を配置するだけなのでi、の値には影響しません。ii

コンパイラと契約を結んだため、コンパイラがそうすることに注意してください。

これが私iのプログラムであり、プログラムの存続期間を通じて変更されることはありません。

コンパイラーは、コントラクトに準拠している限り、必要な最適化を自由に適用できます。この場合は、これを実行します。

于 2012-11-29T04:14:26.660 に答える