Intereting Posts
операции pre и post increment на переменной дают разные результаты на TC и gcc Копирование структуры в массив указателей в функции C Приложение Control C из веб-приложения Java Чтение каждой строки файла в массив Как выполняется обратный вызов из пользовательского пространства в пространство ядра Путь к папке ресурсов в приложении для cocoa Сортировка массива с альтернативными наименьшими наибольшими значениями как установить значение int, переданное параметром функции, и назначить его глобальному, чтобы я мог использовать вне функции? неявное int и неявное объявление функций с gcc-компилятором Y не увеличивается Сохраняется ли куча при выходе программы? Android NDK socket connect () возвращает 0, когда он должен сработать, пока на 3g Обтекание C-структур с помощью SWIG Функция C для преобразования необработанного изображения в png C – exec должен немедленно следовать за fork в многопоточном процессе?

Инициализация между типами «const int ** const» и «int **» недопустима, почему?

Используя компилятор V1.8 z / OS XL C, с предупреждениями, поднятыми с помощью INFO (ALL), я получаю следующее предупреждение в строке 4 приведенного ниже кода:

WARNING CCN3196 Initialization between types "const int** const" and "int**" is not allowed. 1 int foo = 0; 2 int *ptr = &foo; 3 const int * const fixed_readonly_ptr = ptr; 4 const int ** const fixed_ptr_to_readonly_ptr = &ptr; 

Я не могу склонить голову, почему я получаю это предупреждение. Если я могу назначить int указатель на указатель const на const int (строка 3), то почему я не могу назначить адрес указателя int указателю const на указатель на const int? Что мне не хватает?

Обратите внимание, что приведенный выше код представляет собой пример с уменьшенным изображением, в котором показана проблема, с которой я сталкиваюсь в небольшом количестве кода. Реальный контекст заключается в том, что у меня есть указатель const на указатель на struct (struct s ** const) и передаю его как аргумент функции, параметр которого определяется как указатель const на указатель на const struct (const struct s ** Const). Это связано с тем, что функция не будет изменять данные в структуре (отсюда первая константа) и не изменяет параметр указателя, который всегда содержит адрес, переданный (следовательно, второй const). Значение указателя, на которое указывает указатель, может быть изменено путем (именно поэтому между ними нет третьей константы).

Правило C состоит в том, что вы можете преобразовать указатель на что-то в указатель на const что-то, но что-то должно быть точно такого же типа, включая константу и неустойчивую квалификацию дальше по цепочке.

Обоснованием этого правила является то, что если вторая из этих двух линий была разрешена:

 int *ptr; const int ** const fixed_ptr_to_readonly_ptr = &ptr; 

то это может быть использовано для нарушения безопасности типа без литья.

 const int i = 4; // OK, both sides have type const int * *fixed_ptr_to_readonly_ptr = &i; // the value of fixed_ptr_to_readonly_ptr is still &ptr // the value of ptr is now &i; *ptr = 5; // oops, attempt to change the value of i which is const 

Это нарушение безопасности типа. Рассмотрим этот код (я немного перепутал const чтобы дать понять, относится ли это к указателю или указателю, но семантически это означает то же самое):

 int* p = 0; int const** pp = &p; // presumably ok int const c = 123; *pp = &c; // okay, &c is int const*, and *p is int const* lvalue *p = 666; // okay, *p is int lvalue // wait, so we just changed the value of (const) c above, with no const_cast! 

Это нарушение типа безопасности. Вероятно, вы захотите использовать const int * const *. См. http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17.