Причина в простоте использования. char *
может автоматически преобразовываться в const char *
, но char **
не может автоматически преобразовываться в const char **
, и фактический тип указателя (чей адрес передается), используемый вызывающей функцией, с большей вероятностью будет char *
чем const char *
. Причина, по которой это автоматическое преобразование невозможно, заключается в том, что существует неочевидный способ, с помощью которого можно удалить квалификацию const
через несколько этапов, где каждый шаг выглядит совершенно корректным и правильным сам по себе. Стив Джессоп привел пример в комментариях:
если бы вы могли автоматически конвертировать char**
в const char**
, то вы могли бы сделать
char *p;
char **pp = &p;
const char** cp = pp;
*cp = (const char*) "hello";
*p = 'j';.
Для обеспечения безопасности const одна из этих строк должна быть недопустимой, а поскольку все остальные операции выполняются совершенно нормально, это должно быть cp = pp;
Намного лучше было бы определить эти функции, взяв void *
вместо char **
. И char **
, и const char **
могут автоматически преобразовываться в void *
. (пораженный текст был на самом деле очень плохой идеей; он не только предотвращает какую-либо проверку типов, но C фактически запрещает объекты типа char *
и const char *
для псевдонима.) В качестве альтернативы, эти функции могли бы принимать аргумент ptrdiff_t *
или size_t *
, чтобы сохранить смещение конца, а не указатель на него. В любом случае это часто более полезно.
Если вам нравится последний подход, не стесняйтесь писать такую обертку вокруг стандартных функций библиотеки и вызывать вашу обертку, чтобы оставшаяся часть кода была const
чистой и не содержащей приведений.