> Тем не менее, в чистом C это все еще дает предупреждение, и я не понимаю, почему
Вы уже определили проблему - этот код неверен. «Правильное значение констант» означает, что, за исключением случаев, когда приведения const_cast и C-стиля удаляют констант, вы никогда не можете изменять константный объект с помощью этих указателей или ссылок констант.
Значение const-правильности - const в значительной степени обнаруживает ошибки программиста. Если вы объявляете что-то как const, вы заявляете, что не думаете, что это должно быть изменено - или, по крайней мере, те, кто имеет доступ только к const-версии, не должны иметь возможность его изменять. Рассмотрим:
void foo(const int*);
Как объявлено, foo не имеет разрешения для изменения целого числа, на которое указывает его аргумент.
Если вы не уверены, почему код, который вы разместили, не является правильным, рассмотрите следующий код, только немного отличающийся от кода HappyDude:
char *y;
char **a = &y; // a points to y
const char **b = a; // now b also points to y
// const protection has been violated, because:
const char x = 42; // x must never be modified
*b = &x; // the type of *b is const char *, so set it
// with &x which is const char* ..
// .. so y is set to &x... oops;
*y = 43; // y == &x... so attempting to modify const
// variable. oops! undefined behavior!
cout << x << endl;
Неконстантные типы могут преобразовываться в константные типы только особым образом, чтобы предотвратить любое обходное значение const для типа данных без явного приведения.
Объекты, первоначально объявленные как const, особенно специфичны - компилятор может предположить, что они никогда не изменятся. Однако, если 'b' можно присвоить значение 'a' без приведения, вы можете непреднамеренно попытаться изменить переменную const. Это не только нарушит проверку, которую вы попросили сделать компилятор, запретит вам изменять значение этой переменной, но также позволит вам нарушить оптимизацию компилятора!
На некоторых компиляторах будет напечатано «42», на некоторых «43», а в других программа будет аварийно завершена.
Edit-дополню:
HappyDude: Ваш комментарий точный. Либо C-язык, либо используемый вами C-компилятор трактует const char * const * принципиально иначе, чем язык C ++. Возможно, стоит отключить предупреждение компилятора только для этой строки исходного кода.
Редактировать-удалить: опечатка