Страницы

Поиск по вопросам

вторник, 10 декабря 2019 г.

Недопонимание с const

#c #указатели #const


Допустим, я создаю в main() массив указателей, под которые позже выделяю память и
инициализирую посредством функции fgets(). 

int main(void){    
    char *p[5];
    ............
   /* инициализация */
}


Затем я хочу отсортировать данный массив указателей и вызываю функцию sorting().
Для того, чтобы случайно не изменить данные в массиве указателей, аргумент функции
sorting я сделаю const, тобишь: 

void sorting(const char **p){
/* функция сортировки указателей */
}


Однако при вызове данной функции из main(), я получаю ошибку

int main(void){
.............
.............
sorting(p); 

}


предупреждение:


  passing argument 1 of ‘sorting’ from incompatible pointer type [-Wincompatible-pointer-types]
     sorting(p);
  expected ‘const char **’ but argument is of type ‘char **’
  void sorting(const char **p){


Насколько мне известно, то const значения можно инициализировать НЕ const значениями,
но это я читал для просто указателей. Скажите, пожалуйста, как решить данную проблему?
    


Ответы

Ответ 1



Ваше желание вполне понятно и естественно, но тем не менее в С не разрешено неявное приведение типа от char ** к const char **. На первый взгляд вам кажется, что вы просто запрещаете модификацию строк, но вместе с этим вы открываете другую "дыру" в защите константой корректности: если бы это было возможно, то внутри вашей функции sorting вы могли бы спокойно сделать, например p[0] = <адрес какого-то константного объекта типа char>; // Например: // static const char s[] = "Hello World!"; // p[0] = s; что привело бы к тому, что p[0] в main (имеющее тип char *) стало бы указывать на константный объект. И вы этого добились бы без применения явного приведения типа (!). Вот для того, чтобы не открывать такой дыры в защите, С не разрешает неявных преобразований T ** -> const T **. Красивого решения тут навскидку не придумаешь... В main вам, допустим, нужен именно char *[], а в sorting вы, допустим, хотите получать именно const char *[]. В такой ограниченной ситуации остается только применить явное приведение типа. Чтобы не замусоривать код явными приведенями можно, если вам не претит такая практика, спрятать его в макро #define sorting(p) sorting((const char **) (p))

Комментариев нет:

Отправить комментарий