Если верить вашему тегу C, gcc выдает предупреждение, так как типы различаются как для вашего примера, так и для const double * const * const * d
. В C ++ это ошибка в коде OP, но подход slap-const -where допустим.
Причина, по которой компилятор предупреждает вас, заключается в том, что указатель на указатель (или дальнейшее косвенное обращение) позволяет вернуть указатель вызывающей стороне путем изменения местоположения, на которое указывает параметр.
Если цель указателя объявлена как const, тогда вызываемая функция ожидает, что значение, которое она помещает туда, будет возвращено как const.
Более простой случай передачи T**
в const T**
, который показывает, почему это ошибка:
void foo ( const char ** z )
{
*z = "A";
}
int main (int nargs, char** argv)
{
char* z = 0;
char** d = &z;
// warning in C, error in C++
foo ( d );
// bad - modifies const data
z[0] = 'Q';
}
const
в C означает, что данные не изменятся. const
в C ++ означает, что данные не будут изменяться публично - изменяемые данные в объекте C ++ могут изменяться. Компилятор AC может оптимизировать свой код так, чтобы он где-то кэшировал некоторые данные const
, но компилятор C ++ не может этого сделать из-за возможной изменчивости, поэтому имеет более слабое ограничение: вы не можете возвращать данные const в неконстантные как указано выше. Таким образом, в C ++ double***
можно привести к const double * const * const * d
, поскольку дополнительные const
предотвращают возврат неизменяемой памяти, но в C он генерирует предупреждение и возможные ошибки, если компилятор оптимизирует повторный доступ к памяти в другом месте.