これが私の問題です、問題はコメントにあります
const int a = 5;
const_cast<int&>(a)=7; //throw over const attribute in a,and assign to 7
std::cout<<a<<std::endl; //why still out put 5!!!!!!!!!!
誰がその理由を教えてくれますか? また、これらの問題を説明する書籍もありますか? ありがとう!
これが私の問題です、問題はコメントにあります
const int a = 5;
const_cast<int&>(a)=7; //throw over const attribute in a,and assign to 7
std::cout<<a<<std::endl; //why still out put 5!!!!!!!!!!
誰がその理由を教えてくれますか? また、これらの問題を説明する書籍もありますか? ありがとう!
ドラフト C++ 標準セクション7.1.6.1
cv-qualifiers パラグラフ4は次のように述べています。
[...] const オブジェクトの存続期間中 (3.8) を変更しようとすると、未定義の動作が発生します
したがって、どのような動作も可能ですが、これを行うべきではなく、この動作に依存することは絶対にできません。もちろん、 const_castには、 Is const_cast safe?で受け入れられた回答として有効な用途があります。言います:
const_cast は、もともと非 const だった変数をキャストしている場合にのみ安全です。[...]
このライブの例から、現在の値を読み取る代わりに値を使用するだけで、最適化をgcc 4.8.1
行わずに表示される結果の 1 つの方法を確認できます。5
movl $7, (%rax)
movl $5, %esi
movl $_ZSt4cout, %edi
このnon const
場合、次のように表示されます。
movl $7, -4(%rbp)
movl -4(%rbp), %eax
movl %eax, %esi
movl $_ZSt4cout, %edi
これ (編集: 上記で正確に使用した方法) は明示的に未定義の動作であるため、コンパイラはあなたをだましています。a
ステートメントと同じスコープで定義された定数cout
を確認すると、ほとんどの場合、メモリを確認する必要さえありません。
コンパイラをだますためにもっと不自然な例を作成することもできますが、次の変更により、少なくとも gcc で必要な結果が得られます。
volatile const int a = 5;
明確にするために、すべての const_cast の使用が未定義の動作であるとは限りません。WhozCraig の例を参照してください。