2017-04-10 9 views
0

私はconst_castを<>とそれが引き起こす混乱についてインターネットとStackOverflowのを探索し、私は、しかし、私はまだ疑問を持っている、便利なものを見つけました。このコードを考慮C++ constが明示的ではない場合?

は、

#include <iostream> 
using namespace std; 

int main(void) 
{ 
    const int a = 1; 
    int *p = const_cast<int*>(&a); 
    *p = 2; 

    cout << "value a="<< a << endl; 
    cout << "value *p=" <<*p << endl; 
    cout << "address a=" <<&a << endl; 
    cout << "address p=" <<p << endl; 
} 

出力は次のとおり

値A = 1つの
値* P = 2つの
アドレスA = 0x69fef8
アドレスp = 0x69fef8

私はそのようなコードのMAを見つけましたy結果はで、未定義の動作になります。

あなたはのconst性を捨てた場合:私も、この引用を見つけた

(例えばコンパイラが最適化するために、S「の1とS」のすべてのaを置き換えることができ、ひいてはキャストは意味を持ちません)明示的に がconstとして宣言されていて、それを変更しようとしたオブジェクトは、結果は です。

ただし、 がconstとして明示的に宣言されていないオブジェクトのconstnessをキャストすると、安全に変更できます。

と、この:C++は 変数にconst性を削除したり、追加するconst_castを提供

注意。しかし、constityを取り除くときには、 定数ではない参照への参照/ポインタを削除するために使用する必要があります。

int b = 1; 
const int a = b; 

出力である:

次に、上記のコードに次の変更考慮

値a = 2
値*はP = 2
アドレス= 0x69fef4
アドレスp = 0x69fef4

私がいることを理解:int a = 1

aはコンパイル時に処理され、定数式です。 int a = b
aはないが、それは実行時にのみ処理することができます。

hereに記載されているように。

私の質問:

のconst宣言明示的である、とするとき、それはないですか?どのようにもともと非constなのでしょうか?

+1

*「int a = 1」の「 'a」は、コンパイル時に処理される定数式です。そのような保証はC++ではありません。 'constexpr'変数だけがそのような保証を提供します。 – WhiZTiM

+0

@WhiZTiMシニカルでない限り、複雑さに対する実装の定義された制限を読んで、 'constexpr'は0でなければならないので、' constexpr'は無意味です。 – nwp

+0

いいえ、 "未定義の動作が発生する可能性があります" - "**は**未定義の動作"を持っています。 –

答えて

5

が有効単純な反例:この例では

void foo(const int *a) {   // Pointer-to-const here 
    int *p = const_cast<int*>(a); 
    *p = 2; 
} 

int main() { 
    int a = 1;      // But underlying object is not const 
    foo(&a); 
} 
+0

私は2番目の行が次のようになると思います: 'int * p = const_cast (a);' – Shadi

+0

@Shadi - 良いキャッチ、ありがとう! –

3

bはないが

int b = 1; 
const int a = b; 

aトップレベルconstあります。

あなたはこのような関数に渡すした場合:あなたはトップレベルconstオブジェクト、初めからconstとして宣言されたオブジェクトを変更しているので、

void f(const int &i){ 
    const_cast<int &>(i)++; 
} 

その後、f(a)は違法であり、したがって、プログラムは未定義の動作を示します。
一方、がconstで始まっていないので、constがパラメータ変換によって追加されてから、もう一度constが取り除かれたので、f(b)は問題ありません。 bが変更を開始したので、追加されたconstを削除して修正することができます。

+0

両方とも正常に動作しています。期待された結果であっても違法であるということを意味しない限り、正しいものです。この場合、問題の第2コードも不正です。しかし、私はどこかで読んだ、それはいいです。 OKでないものは 'int a = 1'、' f(a) 'です。どう思いますか? – Shadi

+0

@Shadiあなたは不運になる可能性があり、コンパイラはあなたが望むことをすることを決定しますが、標準に従ってそれは未定義の動作であり、コンパイラやコンパイラの最適化を変更するとコードが壊れる可能性があります。私はあなたが指している質問の第2のコードを知りません。 – nwp

関連する問題