2012-01-21 8 views
4

私は次のコードを持っている:const_castはC++では動作しませんか?

const int k=1; 
    int *p=const_cast<int *>(&k); 
    cout<<"k before="<<*p<<endl; 
    *p=10; 
    *const_cast<int *>(&k)=12; 
    cout<<"k after="<<k<<endl; 

出力されました:

k before=1 
k after=1 

はなぜここキャストの仕事をCONSTないのですか?あなたは、値への書き込みconstを捨てた場合

答えて

2

const_castは、最初にconstと定義されていなかったオブジェクトへのポインタをconstと受け取った場合に通常使用されます。オブジェクトが元々constとして定義されていた場合、そのオブジェクトを変更しようとすると未定義の動作が発生します。 const_castがなければ、コンパイラはそれをやろうとしません(コードはコンパイルされません)。

キャストは、しかし、あなたは何をやっている知っている確信していると、コンパイラはただ黙ってあなたの代わりに任意のエラー/警告メッセージを与えることを言ったことを行う必要があるので、それは、本当に安全なのコンパイラに指示します通常と同じように。残念なことに、この場合はではなく、は本当に安全ですが、コンパイラにシャットダウンして実行するように指示しているので、少なくともほとんどのコンパイラで警告は表示されません。

あなたがするべきことは、kが本当にconstかどうかを判断することです。本当にそれを変更する必要がある場合は、それを通常(非const)変数として定義する必要があります。あなたが特定のコードの少量のみがそれを修正することができるようにしたい場合は、/(一つの可能​​性のための)小さなクラスにそれはプライベート作ることができる可能性があり:今

class my_int { 
    int k; 
public: 
    my_int() : k(1) {} 

    do_mod() { k = 10; } 

    operator int() { return k; } 
}; 

do_modは直接kを変更することができます。他のコードでは、intであるかのようにmy_intオブジェクトを使用できますが、その値を変更することはできません。本質的には、それは右辺値のように動作します。

は公平に、私はおそらくいくつかの鋳造を行って、それ本当に試みは、他のコードkの値を変更することができるかどうかということを指摘すべきです。 Bjarne氏によると、C++の保護メカニズムは意図的な破壊ではなく、事故を防ぐためのものです。

12

const_castundefined behaviourの原因となります。あなたがここに見たように、何もしないことは有効な動作です。

あなたの特定の例では、どのような可能性が起きたことは、コンパイラはkconstストレージ・クラスで宣言されていることを認識していることである(合法的に)それができないことを知っているの変化、および

cout<<"k after="<<k<<endl; 

を置き換えます

cout<<"k after="<<1<<endl; 

最適化をオフにすると、別の結果が得られる場合もあれば、そうでない場合もあります。

キャストアウェイconstが未定義のビヘイビアを呼び出す理由は、このような最適化をコンパイラが自由に行うためです。 constの変数を変数constに自由にキャストして書き込むことができれば、constはコンパイラにとって絶対に意味のないものになります。

+5

コンパイラは 'const'オブジェクトを読み出し専用メモリに置くことができます。この場合、このプログラムはアクセス違反でクラッシュする可能性があります。 –

+0

constとして定義されているオブジェクトからconstnessをキャストすると、未定義の動作が発生します。それほどコストがかからないオブジェクトを指す参照からconstを外した場合。 –

4

あなたがしていることは未定義の動作です。 const

+2

実際には、本来は 'const'であったオブジェクトは' const_cast'ではなく、未定義の動作を「変更しようとしています」。 –

+0

@BenVoigt私は自分の答えを変更しました –

+1

オブジェクト 'k'は単に"もともとconst "ではありません。それは創造されて以来のものであり、生涯が延びる限り長く続くでしょう。 * const *であるオブジェクト(変数を含む)は変更できません。 –

関連する問題