の宣言には、最初にconst
と書かれています。
は
void f(struct_type *const data[], unsigned n);
/*...*/
f(v, n);
を使用してみてください、あなたは同じ警告を取得することはありません。あなたはf
void f(const struct_type *const data[], unsigned n);
/*...*/
f((const struct_type * const *) v, n);
を呼び出すときに別の方法として、あなたはv
を唱えこれは少し直感に反するが、Cには、あなたはpointer-to-pointer-to-const
ためpointer-to-pointer-to-nonconst
を渡すことはできません。彼らは特別な例外を作成してにpointer-to-nonconst
を渡すことができました。
はここでよくある質問質問"Why can't I pass a char **
to a function which expects a const char **
?"です:
は、あなたが使用することができますpointer-to-T
pointer-to-const-T
が期待されている(いずれかのタイプT
のため)。しかし、修飾されたポインタ型でわずかなミスマッチを許すルール(明示的例外)は再帰的には適用されず、トップレベルでのみ適用されます。 (const char **
はpointer-to-pointer-to-const-char
であり、例外は、従って、適用されない。)
もしconst char **
ポインタにchar **
値を割り当てることができない理由は幾分あいまいです。 const
修飾子がまったく存在するとすれば、コンパイラはconst
の値を変更しないという約束を守るのを手助けしたいと考えています。それでchar *
をconst char *
に割り当てることができますが、それ以外の方法ではありません。をconst
に追加するのは明らかですが、それを取り除くのは危険です。ただし、割り当ての以下のより複雑な一連の行ったとします。3行目で
const char c = 'x'; /* 1 */
char *p1; /* 2 */
const char **p2 = &p1; /* 3 */
*p2 = &c; /* 4 */
*p1 = 'X'; /* 5 */
を、我々はconst char **
にchar **
を割り当てます。 (コンパイラは文句を言うべきです。)4行目でconst char *
にconst char *
を割り当てます。これは明らかに合法です。 5行目では、char *
が指摘するものを修正します。これは合法的であると考えられています。しかし、p1はcを指して終わり、const
です。これは、p2が本当にp1だったので、第4行目にあります。これは、行3で設定されました。これは、許可されないフォームの割り当てです。これは、行3が許可されていない理由です。
char **
をconst char **
に割り当てる(3行目と元の質問と同様)ことはすぐには危険ではありません。しかし、それはp2の約束(最終的に指摘された価値が変更されないこと)が保たれないという状況を設定します。
(C++を使用すると、警告を発生させることなく割り当てのより多くの種類を作ってみようconst
-qualifiedポインタを割り当てるためのより複雑なルールを持っているが、それでもconst
値を変更するための不注意の試みから保護します。C++はまだconst char **
にchar **
を割り当てることができませんが、それはあなたが* char **
const char * const
に割り当てることで逃さない。)Cで
、あなたが割り当てたり、間接の最初のレベル以外での修飾子ミスマッチを有するポインタを渡す必要がある場合は、明示的なキャストを使用する必要があります。 (この場合は(const char **
))、いつものように、そのようなキャストの必要性は、より深いキャストが実際に修正しない問題。
参考資料:ISO Sec。 6.1.2.6、Sec。 6.3.16.1、Sec。 6.5.3 H & S Sec。 7.9.1これはあなたのために働くかどう頁221-2
警告を受け取っているのは、どのラインですか? – LeopardSkinPillBoxHat