Почему это позволяет продвижение от (char *) до (const char *)? - PullRequest
4 голосов
/ 20 апреля 2009

Учитывая, что scanf имеет (const char *) в документации от Microsoft и ответ на этот вопрос что, черт возьми, происходит, когда я делаю то же самое для (char **) ) повышение до (const char **)?

В основном, почему это компилируется?

#include <stdio.h>
int main(int argc, char **argv)
{   
    char szArray[50];
    int  i = 0;
    strcpy(szArray,"10");
    /* the following code is upcasting the (char *) to (const char *) */
    sscanf(szArray,"%d",&i);
    return 0;  
}

А почему не скомпилируется?

#include <stdio.h>
void processargs(const char **p)
{ 
}
int main(int argc, char **argv)
{
    processargs(argv);          
    return 0;  
}

Кажется, что оба делают одно и то же с указателем!

Ответы [ 4 ]

12 голосов
/ 20 апреля 2009

char** -> const char ** опасно, так как вы можете случайно изменить базовый объект const.

Правильный способ написать, что вы хотите:

void processargs(const char * const *p)
{ 
}
3 голосов
/ 20 апреля 2009

Вам разрешено увеличивать ограничение доступа, вы просто не можете уменьшить его. Переход от обычного указателя к константному указателю - это нормально, переход от константного указателя к нормальному указателю - нет.

Второй пример не компилируется, поскольку вы не конвертируете указатель в константный указатель, вы конвертируете указатель в один тип (char*) в другой (const char*). Например, вы можете изменить char** на char* const*, но не const char**.

2 голосов
/ 20 апреля 2009

Проверьте, прояснилось ли это для вас:

char * a_mutable = /*...*/;
const char * a_constant = /*...*/;

char **pointer_to_mutable = &a_mutable;   /* ok */

const char **pointer_to_constant = &a_constant;   /* ok */

pointer_to_constant = pointer_to_mutable;   /* oops, are you sure? */

*pointer_to_constant = a_mutable;   /* valid, but will screw things around */

Последняя строка действительна, поскольку pointer_to_constant является изменяемым указателем на изменяемый указатель на постоянный символ, но это может привести к поломке, поскольку a_constant указывает на a_mutable. Вот почему вам не разрешено pointer_to_constant получать содержимое pointer_to_mutable.

0 голосов
/ 20 апреля 2009

Ваш первый пример работает, потому что вы конвертируете rvalues ​​ из char* в const char*, что нормально (в основном потому, что вы не можете присвоить rvalues). Второе - нет, потому что целью (неконстантного) указателя всегда является lvalue.

Просто попробуйте (возможно, с помощью компилятора), какие операции вы можете выполнять с char**, какие работают с const char**, и подумайте, взаимозаменяемы ли и какие типы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...