61

非 const データへのポインターは、同じ型の const データへのポインターに暗黙的に変換できます。

int       *x = NULL;
int const *y = x;

追加のインダイレクションに一致する const 修飾子を追加すると、論理的には同じように機能するはずです。

int       *      *x = NULL;
int       *const *y = x; /* okay */
int const *const *z = y; /* warning */

ただし、フラグを指定して GCC または Clang でこれをコンパイルすると-Wall、次の警告が表示されます。

test.c:4:23: warning: initializing 'int const *const *' with an expression of type
      'int *const *' discards qualifiers in nested pointer types
    int const *const *z = y; /* warning */
                      ^   ~

const追加の修飾子を追加すると、「ネストされたポインター型の修飾子が破棄される」のはなぜですか?

4

3 に答える 3

59

const1 レベルの深さしか追加できない理由は微妙で、comp.lang.c FAQ の質問 11.10 で説明されています。

簡単に言えば、あなたの例に密接に関連するこの例を考えてみましょう:

const int i;
int *p;
int const **z = &p;
*z = &i;
/* Now p points to i */

C では、最初に指定されたレベルで修飾子を破棄する代入のみを許可することで、この問題を回避しています (したがって、zここへの代入は許可されません)。

const2番目のレベルは、割り当て*zがとにかく許可されないことを意味するため、正確な例はこの問題に悩まされません。C++この正確なケースでそれを許可しますが、C のより単純なルールは、ケースと上記の例を区別しません。

于 2011-02-20T07:21:02.563 に答える
12

他の回答でリンクされている FAQ エントリは、次のコードが許可されていない理由を説明しています。

int **x = whatever;
const int **z = x;

ただし、コードconst int *const *z = x;はまったく異なり、FAQ で提起された同じ欠陥には悩まされていません。

実際、後者のコードには概念的に何の問題もありません。それが許可されていないのは C 仕様の単なる欠陥であり、C プログラマーは醜いキャストをコードに含めることを強いられます。

C が C++ と同じ規則を使用することは可能でした。しかし、C 標準委員会はそうすることに決めませんでした。

于 2015-04-10T03:46:57.520 に答える