powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / gcc и const char**
12 сообщений из 12, страница 1 из 1
gcc и const char**
    #33883518
Bless
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
int main(){
  char *st="123";
  const char **s;
  s=&st;
  return  0 ;
}
Почему gcc ругается нехорошими словами
invalid conversion from 'char**' to 'const char**'

Что неправильно?
Вроде ж ничего криминального в таком присванивании нет.
...
Рейтинг: 0 / 0
gcc и const char**
    #33883653
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
так у тебя константный указатель на указатель на чар.
а ты его менять хочешь :)
разве менять константу не криминал?
...
Рейтинг: 0 / 0
gcc и const char**
    #33884137
Bless
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex_kтак у тебя константный указатель на указатель на чар.
а ты его менять хочешь :)
разве менять константу не криминал?

Криминал.
А разве s - это константный указатель?
Если бы это было так, то, во-первых, компилятор бы ругнался (наверное) на строчку
Код: plaintext
const char **s;
словами типа "неиниализирован константный указатель"

А во-вторых, в коде
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int main(){
  //f(&months[0]);
  char *st="123";
  const char **s1;
  const char **s;
  char x;
  s=s1; //----------------------
  //s=&st;
  return  0 ;
}
На строчке s=s1; должен был бы заругаться аналогично проблемному фрагменту, а не ругается.

Я хотел объявить s указателем на указатель на константу типа char.
Если я ошибаюсь и s - это не то, что я о нем думаю, то как правильно его объявить?

Кстати, проблемный фрагмент без нареканий компилирует старенький BC3.1.
...
Рейтинг: 0 / 0
gcc и const char**
    #33884195
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще-то, чему либо константному, что либо присваивать не хорошо!

Во втором случае константы меняются между собой данными, но не перестают быть константами. Это сделано только из-за того, чтобы была возможность передавать их куда-нибудь.
...
Рейтинг: 0 / 0
gcc и const char**
    #33884316
Bless
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkhВообще-то, чему либо константному, что либо присваивать не хорошо!
Во втором случае константы меняются между собой данными, но не перестают быть константами. Это сделано только из-за того, чтобы была возможность передавать их куда-нибудь.

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

Я только изучаю c++ (собственно, и вопрос-то возник при попытке решить упражнения к разделу 5 из книги Страуструпа) и весьма возможно, что я ошибаюсь, считая s указателем на указатель на константу типа char, но осмелюсь утверждать, что s - уж точно никакой не константный указатель.
Если бы он был константным указателем, то выглядел бы так
char **const s;
и тогда, как и положено, компилятор заругался бы на "неинициализированую константу" в объявлении s.
...
Рейтинг: 0 / 0
gcc и const char**
    #33884447
redskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть простое правило чтобы не путаться в константных указателях. Если const стоит слева от звездочки, то "константность" относится к данным на которые указывает указатель (пардон за масло масляное). Если справа, то к самому указателю.

пример:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
    const char *s = "123";
    const char *s1;

    s1 = s;  // ok
    *s='a';  // error

    char * const s2 = "absd";
    *s2 = 'a';   // ok (хотя так делать не надо :))
    s2 = s1;     // error
...
Рейтинг: 0 / 0
gcc и const char**
    #33884467
Bless
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
redskin


А что можете сказать по сути проблемы? :)
...
Рейтинг: 0 / 0
gcc и const char**
    #33884484
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlessЯ сильно сомневаюсь, что константы имеют возможность меняться между собой данными, как бы сильно ни хотелось их куда бы то ни было передать.


Ну, во первых это видно на предыдущем примере.
Во вотрых, еще пример: данных в функцию с константным параметром.
...
Рейтинг: 0 / 0
gcc и const char**
    #33884540
redskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bless redskin


А что можете сказать по сути проблемы? :)

Хм, так я все сказал в пред. сообщении :)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
int main()
{

   char *st="123";
   char * const *s;
   
   s=&st;
   cout << *s;

   return  0 ;
}

...
Рейтинг: 0 / 0
gcc и const char**
    #33884582
redskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В принципе исходный код можно "поправить", обманув компилер и явно приведя указатель к нужному нам типу:

s=(const char **)(&st);

Но тогда программа будет вести себя странно.
const char ** означает указатель на указатель на константный char. Т.е. после разыменования мы получим доступ к константной строке, которая не должна меняться, по крайней мере этого будут ожидать пользователи. А что на самом деле:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
int main()
{

   char *st="123";
   const char **s;
   
   s=(const char **)(&st);
   cout << *s << endl;       // выводим "константную" строку

   st = "abc";
   cout << *s << endl;       // и еще раз эту же строку. lol

   return  0 ;
}
...
Рейтинг: 0 / 0
gcc и const char**
    #33884625
redskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поэтому правильнее, наверное, менять тип не у s, a у st.

Код: plaintext
1.
2.
3.
   const char *st="123";
   const char **s;
   s=&st;

Теперь s и &st имеют одинаковый тип, можно присваивать сколько душе угодно.
...
Рейтинг: 0 / 0
gcc и const char**
    #33885592
Bless
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
redskin
Но тогда программа будет вести себя странно.
const char ** означает указатель на указатель на константный char. Т.е. после разыменования мы получим доступ к константной строке, которая не должна меняться, по крайней мере этого будут ожидать пользователи. А что на самом деле:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
int main()
{

   char *st="123";
   const char **s;
   
   s=(const char **)(&st);
   cout << *s << endl;       // выводим "константную" строку

   st = "abc";
   cout << *s << endl;       // и еще раз эту же строку. lol

   return  0 ;
}



Неубедительно :)
Применяя вашу логику, странным будет и нижеследующий пример:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
int main(){
  char st[ 4 ]="123";
  const char *s;
  s=st;
  cout<<s<<endl;// выводим "константную" строку
  st[ 0 ]='5';
  cout<<s<<endl;// и еще раз эту же строку. lol
};

Ведь const char * - константная строка, "которая не должна меняться, по крайней мере этого будут ожидать пользователи".

Хотя ничего странного в этом нет.
Все, на что может рассчитывать пользователь, это на то, что эта строка не будет изменена посредством s, не более того.


В общем, я нашел себе удовлетворяющий меня ответ:
из книги Страуструпа The C++ Programming Language (Third Edition)
раздел C.6.2.3 "Pointer and Reference Conversions" касательно неявных преобразований указателей сказано, что:
1) можно любой указатель (за исключение указателей на функции и члены)преобразовать к void*
2) можно указатель на класс потомок преобразовать к классу предку
3) константное выражение, равное нулю может быть преобразование к любому указателю.
4) T* может быть неявно преобразован к const T*.

Все. Больше никаких других неявный преобразований(я надеюсь, Страуструп ничего не упустил) в c++ ПРОСТО НЕТ, сколь бы логичными мне эти другие ни казались.
Из этих пунктов только последний мог бы подойти к моему примеру. НО
Преобразуем фрагмент
Код: plaintext
1.
2.
3.
char *st="123";
const char **s;
s=&st;
в аналогичный ему
Код: plaintext
1.
2.
3.
4.
5.
char *st="123";
char ** pst;
const char **s;
pst=&st;
s=pst;
а затем в
Код: plaintext
1.
2.
3.
4.
5.
6.
typedef char* T;
T st="123";
T * pst;
const char **s;
pst=&st;
s=pst;

Отсюда видно, что строка s=pst, где pst имеет тип T*, будет корректной только если s (согласно пункту 4 неявных соглашений) имеет тип const T*,
т.е
Код: plaintext
char *const * s

а никак не
Код: plaintext
const char ** s


Спасибо за пример, давший толчок в нужном направлении.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
int main()
{
   char *st="123";
   char * const *s;
   s=&st;
   cout << *s;
   return  0 ;
}

...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / gcc и const char**
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]