Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.07.2016, 16:06   #1
m3g4z0rdEX
Пользователь
 
Регистрация: 14.10.2015
Сообщений: 17
По умолчанию Вопрос по стандарту, приведения квалификаторов в C++

Читаю Дьюхэрста, наткнулся на главу 32 - преобразование указателя на указатель.
Автор ведет отсылку к стандарту С++ - 4.4.
При этом говориться, что указатель на указатель типа, можно преобразовать в другой указатель на указатель, если:
1. Указатели типа подобны
2. Если первый(не нулевой !) квалификатор в кортеже первого элемента константный, то и у второго элемента, на том же месте в списке квалификатоов он должен быть константным.
3. Если значения различны, то требуется что бы все квалификаторы второго типа, до данного были константными, кроме нулевого.

И дальше даются примеры, которые я без труда осилил и понял. А вот самый первый пример, я не понял, вот он:
PHP код:
char** ppc 0;
const 
char** ppcc 0;
ppcc ppc ошибка
Здесь:
T1 - квалификаторы none, none
T2 - квалификаторы const, none

И проходя по пунктам правил, я прихожу к мнению, что все должно бы и скомпилироваться. Где я не прав, подскажите ?
m3g4z0rdEX вне форума Ответить с цитированием
Старый 14.07.2016, 16:16   #2
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

"Нулевой" квалификатор это тот, который последний:
Код:
char** const ppcc = ppc;
это он не учавствует в cv-квалификикации указательного типа.
Если интересует подробнее, то могу попозже написать подробнее.
Может станет понятнее, а может и нет.
Croessmah вне форума Ответить с цитированием
Старый 14.07.2016, 16:18   #3
m3g4z0rdEX
Пользователь
 
Регистрация: 14.10.2015
Сообщений: 17
По умолчанию

Тогда можете описать какие квалификаторы будут в данном случае ? Запутался.
m3g4z0rdEX вне форума Ответить с цитированием
Старый 14.07.2016, 16:25   #4
m3g4z0rdEX
Пользователь
 
Регистрация: 14.10.2015
Сообщений: 17
По умолчанию

Цитата:
Сообщение от Croessmah Посмотреть сообщение
"Нулевой" квалификатор это тот, который последний:
Код:
char** const ppcc = ppc;
это он не учавствует в cv-квалификикации указательного типа.
Если интересует подробнее, то могу попозже написать подробнее.
Может станет понятнее, а может и нет.
Интересует !
m3g4z0rdEX вне форума Ответить с цитированием
Старый 14.07.2016, 16:38   #5
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Цитата:
Сообщение от m3g4z0rdEX Посмотреть сообщение
Интересует !
Тогда скопирую свои посты с другого форума, писать два раз не хочется.
Вопрос был таков:
Цитата:
Код:
void f (const int** const a) {
  ...
}
Вот кратко результаты моих "экспериментов", на основании которых я сделал такие выводы (в круглых скобках "()" тип параметра функции, в угловых "<>" фактический тип передаваемого аргумента, через тире "-" результат попытки:
(int ** const) или
(int **)
<int** const> - Ok
<const int**> - Error

(const int ** const) или
(const int **)
<int** const> - Error
<const int**> - Ok
Ответ:
В варианте
(int ** const) или (int **) - тип T1(конечный тип)

Параметр функции имеет сигнатуру cv-квалификации указательного типа(далее просто - сигнатура) (none , none)

Если Вы передаете:
<int** const> - тип T2
Типы T1 и T2 подобны, т.к. уровень косвенности одинаковый(совпадает кол-во звездочек) и базовый тип тоже одинаков. Если типы не подобны преобразование невозможно.

сигнатура T2 = (none , none) - Сигнатура совпадает полностью с сигнатурой конечного типа, поэтому преобразование разрешено.

Если Вы передаете:
<const int**> - тип T2
Типы T1 и T2 подобны.
сигнатура T2 = (none , const) - Второй cv-квалификатор на совпадает.
При несовпадении соответствующих cv-квалификаторов, преобразование возможно, только если в сигнатуре конечного типа все cv-квалификаторы до несовпадающих будут содержать const. В данном случае
T1_cv_1 = none - T2_cv_1 = none
T1_cv_2 = none - T2_cv_2 = const
как видите, не совпадает квалификатор под номером 2, значит, преобразование возможно только если все квалификаторы до него в сигнатуре T1 будут иметь const. T1_cv_1 не const, значит преобразование невозможно.
------------------------------------------------------------------------------------------------------------------------------------------------
По той же схеме при параметре функции
(const int ** const) или (const int **)- тип T1(конечный тип) c сигнатурой (none, const)

<int** const> - T2. Сигнатура (none,none)
T1 и T2 подобны.
T1_cv_1 = none , T2_cv_1 = none
T1_cv_2 = const , T2_cv_2 = none - не совпадают. T1_cv_1 не const, значит преобразование невозможно.

<const int**> - T2. Сигнатура (none,const)
T1 и T2 подобны. Сигнатуры совпадают. Преобразование разрешено.


Так же в типе есть квалификатор cv_0(тот самый const в параметрах, который ни на что не влияет), но он не входит в сигнатуру cv-квалификации указательного типа, поэтому и не учавствует в разрешении преобразования.

Нарисовал схемку сигнатуры cv-квалификации:
схема cv-квалификации.png
если в cv_x имеется const, то я обозначил как const, если нет - none.

На картинке (const,const,const) - cv_0 не входит в сигнатуру cv-квалификации указательного типа.

Например, для указателя
Код:
int const * const * * const * const * * * const
будет none, none, const, const, none, const, const

Последний раз редактировалось Croessmah; 14.07.2016 в 17:33.
Croessmah вне форума Ответить с цитированием
Старый 14.07.2016, 17:18   #6
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

т.е. для вашего случая:
Код:
char** ppc = 0;
Начальный тип - T1
сигнатура cv-квалификации: none, none, none
Код:
const char** ppcc = 0;
Конечный тип - T2
сигнатура - none, none, const (заметьте, квалификаторы считаются справа-налево)
Подчеркнул то, что не участвует в разрешении преобразования.
у Вас не совпадает последний cv-квалификатор, значит в T2 до него всё должны быть const.
Как видим, это не так.
Чтобы преобразование прошло, должно быть так:
none, const, const
а значит указатель ppcc должен иметь тип:
Код:
const char* const* ppcc = 0;
ppcc = ppc;//тогда это прокатит

Не знаю, будет ли полезна и понятна кому-нибудь эта портянка

Последний раз редактировалось Croessmah; 14.07.2016 в 17:21.
Croessmah вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Си. Как привести код к стандарту С99 Ka2R Помощь студентам 1 13.03.2015 10:47
О надобность приведения к типу hoz Общие вопросы .NET 28 13.02.2015 22:45
Макрос для приведения к одному, одинаковому размеру графиков REztor Microsoft Office Excel 2 23.12.2012 22:28
Битва экстрасенсов. Приведения, души и т.д. TwiX Свободное общение 5 30.10.2011 15:22
Проблема приведения типов Dec(Leprosus) Общие вопросы C/C++ 14 08.05.2008 04:24