2016-10-17 6 views
0

Если мы имеем void foo(const char * const ** bar); и мы называем его char *** bar = malloc(...);, такие как foo((const char * const **) bar); возвращает:Почему вызов функции, которая принимает (const char * const **) с char ***, вызывает флаг -Wcast-qual?

error: to be safe all intermediate pointers in cast from ‘char ***’ to ‘const char * const**’ must be ‘const’ qualified [-Werror=cast-qual] 

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

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

Я понимаю, что флаг является дополнительной один, но он определен как:

-Wcast-qual 

Warn whenever a pointer is cast so as to remove a type qualifier from the target type. For example, warn if a const char * is cast to an ordinary char *. 

Насколько я могу судить, ни один из типов классификатора не удаляются, а мы добавления отборочных типа в сообщите пользователю, что функция не изменяет никаких данных.

Почему упомянутый выше код запускает дополнительное предупреждение -Wcast-qual? Есть ли лучший способ перевести полный malloc'd тройной указатель как функцию только для чтения?

+0

'Есть ли лучший способ перевести полный malloc'd тройной указатель как функцию только для чтения?'Да, не бросайте' malloc' вообще –

+0

Кастинг вызывает ошибку «несовместимого типа указателя». Я на самом деле согласен, нет смысла бросать, но по какой-то причине компилятор этого не допустит. EDIT: Является ли const char * const ** не тем же типом, что и char ***, только с квалификаторами? – jake

+0

Вы компилируете с помощью компилятора C++? –

ответ

0

TL; DR: const char * const ** ->const char * const * const *

Чтобы закончить вопрос, ответ в комментариях по/пользователей/2410359/chux (попросили их сделать пост, но они не имеют). Решение заключалось в использовании const char * const * const *, который не запускает флаг -Wcast-qual. В основном то, что у меня было, было не истинным квалификатором только для чтения, мне нужен был другой уровень.

1

Почему передача char* функции, ожидающей работы char const*?

Это просто понять. Вы не можете изменить строку в вызываемой функции. Ничего страшного.

Почему передача char** функции, ожидающей, что char const** не работает?

Это звучит неинтуитивно, но есть причина. Возьмите эту аналогию с int.

const int a = 10; 
void foo(int const ** ap) 
{ 
    *ap = &a; 
} 

void bar() 
{ 
    int * p = NULL; 
    foo(&p); 
    *p = 20; 
} 

Если вы разрешили использовать это, вы можете изменить a, который const в bar косвенно.

Именно поэтому &p, тип которого int**, не допускается к лишению к int const** неявным образом.

+0

Есть ли способ указать, что ap не будет скопирован на другой указатель? Например, используя ключевое слово 'limit'? Или есть больше сценариев. – jake

+0

@jake, я не думаю, что использование 'ограничения' решит проблему' const' vs non-'const'. –

+0

Я просто попробовал, и, похоже, это не сработало. Я предполагаю, что моя логика «ограничивает» говорит, что только указанный указатель укажет на память, но это действительно не работает, и это не устраняет проблему. – jake

Смежные вопросы