型間の初期化「のconst int型のconst **」と「int型**」は、なぜ許可されていませんか?
質問
ジャッキアップINFO(ALL)を使用して、警告と、V1.8のZ / OS XL Cコンパイラを使用して、私は以下のコードの行4に次の警告を得る:
WARNING CCN3196 Initialization between types "const int** const" and "int**"
is not allowed.
1 int foo = 0;
2 int *ptr = &foo;
3 const int * const fixed_readonly_ptr = ptr;
4 const int ** const fixed_ptr_to_readonly_ptr = &ptr;
私はこの警告を得ている理由のまわりで私の頭をラップすることはできません。私はのconst int型(ライン3)へのconstポインタにint型のポインタを割り当てることができた場合は、なぜ私はのconst int型へのポインタへのconstポインタにint型のポインタのアドレスを割り当てることができませんか?私は何をしないのですか?
上記のコードを注意してくださいちょうど私が少量のコードに遭遇しています問題を示すスリム化の例です。本当の文脈は**私が(構造体S **のconst)を構造体へのポインタへのconstポインタを持っていると、パラメータの関数への引数がconstの構造体(constの構造体Sへのポインタへのconstポインタとして定義されているとしてそれを渡していますということですCONST)。関数は構造体のデータを変更しないであろうからである(それゆえ第一CONST)、それは常に(従って第二CONST)に渡されたアドレスを保持するポインタパラメータを変更しません。ポインタの値によって変更されてもよい指さ(その間の第CONSTがない理由である**)。
解決
Cルールは、あなたが何かをCONSTへのポインタに何かへのポインタを変換できるということですが、それは何か、さらにチェーンダウンconstとvolatile資格を含め、まったく同じタイプである必要があります。
このルールの理論的根拠は、これらの2つのラインの第二は、許可された場合:
int *ptr;
const int ** const fixed_ptr_to_readonly_ptr = &ptr;
これは、キャストせずに型の安全性を破るために使用することができます。
const int i = 4;
// OK, both sides have type const int *
*fixed_ptr_to_readonly_ptr = &i;
// the value of fixed_ptr_to_readonly_ptr is still &ptr
// the value of ptr is now &i;
*ptr = 5;
// oops, attempt to change the value of i which is const
他のヒント
これは、型の安全性違反です。このコードを考えてみましょう(私はそれを明確にそれがポインタや指示先に適用されるかどうかを作るために少し周りconst
をシャッフルが、意味的にはまったく同じことを意味する):
int* p = 0;
int const** pp = &p; // presumably ok
int const c = 123;
*pp = &c; // okay, &c is int const*, and *p is int const* lvalue
*p = 666; // okay, *p is int lvalue
// wait, so we just changed the value of (const) c above, with no const_cast!
これは、型の安全性違反です。あなたは、おそらく代わりに、*のconst int型* constのを使用したいです。 http://www.parashift.com/c++を参照してください。 -faq-LITE / constの-correctness.html#FAQ-18.17 の