Почему C, в отличие от C ++, запрещает добавление const-квалификации на оба уровня указателя на указатель? - PullRequest
0 голосов
/ 04 января 2019

У меня следующая ситуация:

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

Минимальный пример:

void function(const char * const *arr) {
    /* Do something useful */
}

int main(void) {
    char **x;
    /* fill x and *x */
    function(x);
}

При компиляции с помощью gcc или clang thisдает мне предупреждение, что x преобразуется в несовместимый тип указателя.

Хотя я понимаю, почему тип указателя несовместим, если я удаляю второй констант в списке параметров функции (объяснено здесь: Почемупередача char ** как const char ** генерирует предупреждение? ), я не понимаю, почему он несовместим с const.

Компиляция с c ++ - компилятор не выдает мне предупреждение (Смотрите сравнение здесь: https://gcc.godbolt.org/z/YND5U7)

1 Ответ

0 голосов
/ 04 января 2019

Я не понимаю, почему он несовместим с const.

Примечание: const1, const2 определено для ясности, чтобы различать два.

В Сconst2 в const1 char * const2 *arr - это необязательный параметр x.const2 говорит, что function(const1 char * const2 *arr) имеет контракт с кодом вызова, он не изменит то, на что указывает arr.arr указывает на const1 char *.arr может быть const1 char ** или const1 char * const2 *.

В main(), несовместимо, поскольку *x указывает на char *, а не const1 char *.То, на что он указывает, отличается от того, что ожидает function().const1 не является частью function() контракта без записи.Вместо этого const1 char * - это тип, который отличается от char *.

На данный момент я не вижу причин, по которым C нельзя было бы указать по-другому, чтобы разрешить обработку char * как const1 char * в function() - это просто случай, когда C не позволяет этого.

#define const1 const
#define const2 const
void function(const1 char * const2 *arr) {
    // Do something useful
}

int main(void) {
    char **x = 0;
    function(x);  // bad  
    // note: expected 'const char * const*' but argument is of type 'char **'

    const char **x2 = 0;
    function(x2); // OK
}

Нет комментариев к C ++

...