Законно преобразовать pointer-to-non-const в указатель на константу.
Затем, почему не законно преобразовывать указатель на указатель на неконстанту к указателю на указатель на константу?
Например, почему следующий недопустимый код:
char *s1 = 0;
const char *s2 = s1; // OK...
char *a[MAX]; // aka char **
const char **ps = a; // error!
Из стандарта :
const char c = 'c';
char* pc;
const char** pcc = &pc; // not allowed
*pcc = &c;
*pc = 'C'; // would allow to modify a const object
Игнорирование вашего кода и ответ на принцип вашего вопроса, см. Эту запись в FAQ comp.lang.c: Почему можно «Разве я не передаю char ** функции, которая ожидает const char **?
Причина, по которой вы не можете присвоить значение
char **
параметруconst char **
указатель неясен. Учитывая, что квалификаторconst
вообще существует, компилятор хотел бы помочь вам выполнить ваши обещания не изменять значенияconst
. Вот почему вы можете присвоитьchar *
const char *
, но не наоборот: явно безопасно «добавить»const
-ness к простой указатель, но убирать его было бы опасно. Однако предположим, что вы выполнили следующую более сложную серию присваиваний:const char c = 'x'; / * 1 * / char * p1; / * 2 * / const char ** p2 = & p1; / * 3 * / * p2 = & c; / * 4 * / * p1 = 'X'; / * 5 * /
В строке 3 мы присваиваем
char **
константеconst char **
. (Компилятор должен пожаловаться.) В строке 4 мы присваиваемconst char *
const char *
; это явно законно. В строке 5 мы изменяем то, на что указываетchar *
- это должно быть законным. Однакоp1
в конечном итоге указывает наc
, что являетсяconst
. Это произошло в строке 4, потому что* p2
на самом деле былоp1
.Это было настроено в строке 3, которая является назначением формы, которая запрещена, и именно поэтому строка 3 запрещена.
И поскольку ваш вопрос помечен как C ++, а не C, он даже объясняет, какие квалификаторы const
следует использовать вместо этого:
(В C ++ есть более сложные правила для назначения указателей с квалификацией const, которые позволяют создавать больше виды назначений без предупреждений, но все же защищают от непреднамеренных попыток изменить значения const. C ++ по-прежнему не позволяет назначать
char **
параметруconst char **
, но это будет позвольте вам избежать назначенияchar **
наconst char * const *
.)
Поскольку никто не опубликовал решение, вот:
char *s1 = 0;
const char *s2 = s1; // OK...
char *a[MAX]; // aka char **
const char * const*ps = a; // no error!
(http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17 для чего)