Двойной указатель предупреждений о правильности в C - PullRequest
49 голосов
/ 20 февраля 2011

Указатель на неконстантные данные может быть неявно преобразован в указатель на константные данные того же типа:

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 "отбрасывать квалификаторы во вложенных типах указателей"?

Ответы [ 2 ]

47 голосов
/ 20 февраля 2011

Причина, по которой const может быть добавлена ​​только на один уровень глубже, неуловима и объясняется Вопросом 11.10 в FAQ по comp.lang.c .

Вкратце рассмотрим этоПример, тесно связанный с вашим:

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

C позволяет избежать этой проблемы, разрешив назначение только для того, чтобы отменить квалификаторы на первом указанном уровне (поэтому здесь не разрешено присваивание z).

Ваш точный пример не страдает от этой проблемы, потому что const второй уровень означает, что присвоение *z не будет разрешено в любом случае.C ++ разрешил бы в этом конкретном случае, но более простые правила C не различают ваш случай и приведенный выше пример.

8 голосов
/ 10 апреля 2015

Запись FAQ, связанная с другим ответом, объясняет, почему следующий код не разрешен:

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

Однако ваш код const int *const *z = x; совершенно другой, и он не страдает от того же самого изъянапо часто задаваемым вопросам.

Фактически, в последнем коде нет ничего плохого.Это просто недостаток спецификации C, что она не разрешена, и это заставляет программистов на C включать в свой код некрасивые преобразования.

C мог бы использовать те же правила, что и C ++;однако комитет по стандартизации C не решил сделать это.

...