2011-12-20 24 views
8

次のコードはコンパイルしないでください。しかし、g ++では、それはコンパイルします!それはhttp://codepad.org/MR7Dsvlzでコンパイルしてください。(constへのポインタ)から(constへのポインタへの)キャストが無効なC++ですか?

コード:

#include <iostream> 

using namespace std; 

int main() { 
    int x = 32 ; 
    // note: if x is, instead, a const int, the code still compiles, 
    // but the output is "32". 

    const int * ptr1 = & x ; 

    *((int *)ptr1) = 64 ; // questionable cast 
    cout << x ;   // result: "64" 
} 

はこれをコンパイルすることにより、G ++エラーでますか?

+0

constをキャストしたい場合(そしてあなたが許可していることを確信している)、それを行うための慣用的なC++の方法は 'const_cast (ptr1)'です - あなたが見たようにCのキャストも機能します。 –

+1

これは読むのに役立ちます:http://stackoverflow.com/questions/357600/is-const-cast-safe – Pubby

答えて

9

号は、C++標準の§5.4.4によると、Cスタイルのキャストによって行うことができるキャストは以下のとおりです。

— a const_cast (5.2.11), 
— a static_cast (5.2.9), 
— a static_cast followed by a const_cast, 
— a reinterpret_cast (5.2.10), or 
— a reinterpret_cast followed by a const_cast 

これは、広く「離れconst -nessをキャスト」として知られていますコンパイラは、そのコードをコンパイルしなかった場合、標準のその部分に準拠しません。

ildjarnが指摘するように、constのネストをキャストしてconstオブジェクトを変更することは、未定義の動作です。 constへのポインタで指し示されたオブジェクトでも、オブジェクト自体はconstではありません(私の悪い読みを修正するためにR.Martinhoとeharvestに感謝します)ので、このプログラムは未定義の動作をしません。

+0

"いいえ" - だからg ++はコードをコンパイルするべきだったのですか? "コンパイラはそのコードをコンパイルしなかった場合、標準のその部分に準拠しません。" - g ++は標準のその部分に準拠していますか? –

+0

@noshenimあなたの質問は「これをコンパイルするとg ++がエラーになりますか?私は「いいえ」と答えた。したがって、g ++はコードをコンパイルする必要があります。標準のその部分に準拠しています。 –

+3

Noshenim、あなたは矛盾した質問をしました。あなたのタイトル質問への*はい*答えは身体の質問に対する* no *答えでした。次回はもっと注意してください。 –

3

g ++はコードをコンパイルすることでエラーにはなりません。あなたがしたキャストは有効です。

(int *)ptr1は、キャストです。 C++の同等語はconst_cast<int*>(ptr1)です。 2番目のスタイルは読みやすくなります。

しかし、(const変数を変更するために)このキャストを行う必要があるため、デザインに問題があります。

1

*((int *)ptr1) = 64は、*(const_cast<int*>(ptr1)) = 64に相当します。const_castは、キャスト表記を使用すると実行される最初のキャストです。

関連する問題