Почему не законно преобразовывать “указатель на указатель на неконстанту” к “указателю на указатель на константу”

Законно преобразовать pointer-to-non-const в указатель на константу.

Затем, почему не законно преобразовывать указатель на указатель на неконстанту к указателю на указатель на константу?

Например, почему следующий недопустимый код:

char *s1 = 0;
const char *s2 = s1; // OK...
char *a[MAX]; // aka char **
const char **ps = a; // error!
35
задан Alex Shesterov 6 October 2013 в 14:49
поделиться

3 ответа

Из стандарта :

const char c = 'c';
char* pc;
const char** pcc = &pc;   // not allowed
*pcc = &c;
*pc = 'C';                // would allow to modify a const object
35
ответ дан 27 November 2019 в 06:47
поделиться

Игнорирование вашего кода и ответ на принцип вашего вопроса, см. Эту запись в 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 * .)

20
ответ дан 27 November 2019 в 06:47
поделиться

Поскольку никто не опубликовал решение, вот:

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 для чего)

11
ответ дан 27 November 2019 в 06:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: