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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 16.11.2018, 15:39   #1
protoder
Пользователь
 
Регистрация: 16.11.2018
Сообщений: 16
По умолчанию Ошибка инициализации символьной строки

Строка

char* HexFormatString = "Any string";

при компиляции дает ошибку, типа, не могу инициализировать char указатель константным char указателем. Та же ошибка лезет, например,
в printf("FS",... Что совсем странно.


Смысл этой ошибки мне понятен. Я даже знаю, как ее исправить. Разговор не о том. Мне надо понять, почему вообще лезет такая ошибка. По какой-то причине, VC++ посчитал строковый литерал константой.
Важно!!! Подобный код нормально работает как на других С++ компиляторах, так и в других проектах на MSVC++. То есть ошибка наверняка связана с какой-то текущей настройкой компилятора, но я примерно не представляю, какой именно. Может, кто-то сталкивался?
В качестве стандарта у меня выбран С++ 17. Использую недавно скачанную бесплатную русифицированную версию MSVC++.
protoder вне форума Ответить с цитированием
Старый 16.11.2018, 15:58   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Цитата:
Сообщение от protoder Посмотреть сообщение
По какой-то причине, VC++ посчитал строковый литерал константой.
Потому что стал стараться следовать стандарту. В С++03 уже это было деприкарт.

Цитата:
Сообщение от protoder Посмотреть сообщение
То есть ошибка наверняка связана с какой-то текущей настройкой компилятора, но я примерно не представляю, какой именно.
Цитата:
Сообщение от protoder Посмотреть сообщение
В качестве стандарта у меня выбран С++ 17.
p51x вне форума Ответить с цитированием
Старый 16.11.2018, 16:58   #3
protoder
Пользователь
 
Регистрация: 16.11.2018
Сообщений: 16
По умолчанию

Странно. До этого я что-то не помню, что б когда-нить нарывался на такую ситуацию.

>> Потому что стал стараться следовать стандарту.

А есть идеи, как заставить ее расстараться? Ибо ужасно не удобно.
protoder вне форума Ответить с цитированием
Старый 16.11.2018, 17:37   #4
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Цитата:
Сообщение от protoder Посмотреть сообщение
До этого я что-то не помню, что б когда-нить нарывался на такую ситуацию.
Варнинги тоже читать надо.

Цитата:
Сообщение от protoder Посмотреть сообщение
А есть идеи, как заставить ее расстараться? Ибо ужасно не удобно.
Чем?
p51x вне форума Ответить с цитированием
Старый 16.11.2018, 18:16   #5
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Цитата:
Сообщение от protoder Посмотреть сообщение
Ибо ужасно не удобно.
А по смыслу как раз очень удобно. Если этот HexFormatString не предполагается менять по месту, то так и напишите
Код:
const char* HexFormatString = "Any string";
А если предполагается, то передавать туда литерал - ошибка, от которой компилятор и пытается нас избавить.

И как всегда, чтобы успешно выстрелить себе в ногу, можно обмануть компилятор через const_cast. Хотя для сглаживания острых моментов лучше сделать массив:
Код:
char HexFormatString[] = "Any string";
Black Fregat вне форума Ответить с цитированием
Старый 16.11.2018, 19:44   #6
protoder
Пользователь
 
Регистрация: 16.11.2018
Сообщений: 16
По умолчанию

Не удобно тем, что у меня есть уже готовый код, порядка 15000 стирок, который нормально работает на другом компиляторе, и мне его надо перенести на MSVC.

Цитата:
Сообщение от Black Fregat Посмотреть сообщение
А если предполагается, то передавать туда литерал - ошибка, от которой компилятор и пытается нас избавить.
Почему это ошибка? Не вижу на то ни каких оснований. Память под переменную выделена в глобальной области, ни куда она не денется, и какой смысл ее объявлять константной, я не вижу. Другой разговор, если б у нас была Гарвардская архитектура.
Разве что компиллер планирует потом использовать эту же константу для инициализации других переменных. Но - казалось бы, отследить наличие не константной ссылки на нее компилятор в силах.
Но - бог с ним. О том, что для кого очевидно, спорить, на самом деле, еще хуже, чем о вкусах. А разговор не о том.
Разговор о том, что в моем случае возникает проблема с вызовом функции стандартной библиотеки. Например, printf("какой-то формат",...) выдает ту же ошибку. А вот это уже совсем не катит. Кстати, не знаю, почему. Был уверен, что в хедере параметр описан как просто char* почему-то. Нет. char const* const Format. Тогда вообще не понятно, какого фига ругается. При этом такой вариант:
sprintf(Buf, (char*)"0x%X", X);
проходит без сообщений.

Последний раз редактировалось protoder; 16.11.2018 в 20:03.
protoder вне форума Ответить с цитированием
Старый 16.11.2018, 21:04   #7
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Цитата:
Сообщение от protoder Посмотреть сообщение
Память под переменную выделена в глобальной области
Это под переменную. А литерал, на который она указывает - в сегменте констант, который вполне может быть r/o.
Black Fregat вне форума Ответить с цитированием
Старый 16.11.2018, 21:17   #8
protoder
Пользователь
 
Регистрация: 16.11.2018
Сообщений: 16
По умолчанию

Цитата:
Сообщение от Black Fregat Посмотреть сообщение
Это под переменную. А литерал, на который она указывает - в сегменте констант, который вполне может быть r/o.

Этот функционал как-то отключить можно? Меня интересует именно это.
Вернее, не так - как именно его отключить. Что отключить можно, я знаю точно.
protoder вне форума Ответить с цитированием
Старый 16.11.2018, 21:50   #9
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Цитата:
Сообщение от protoder Посмотреть сообщение
По какой-то причине, VC++ посчитал строковый литерал константой.
Т.е. вы считаете вот такой код должен работать?
"helloworld"[5] = 'A';

Цитата:
Сообщение от protoder Посмотреть сообщение
Например, printf("какой-то формат",...) выдает ту же ошибку
Код показывайте, а то у меня ничего такого не выдает.

Цитата:
Сообщение от protoder Посмотреть сообщение
sprintf(Buf, (char*)"0x%X", X);
Наличие приведения типа обычно признак проблемы.

Последний раз редактировалось waleri; 16.11.2018 в 21:53.
waleri вне форума Ответить с цитированием
Старый 17.11.2018, 02:13   #10
protoder
Пользователь
 
Регистрация: 16.11.2018
Сообщений: 16
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Т.е. вы считаете вот такой код должен работать?
"helloworld"[5] = 'A';
А вы считаете, что

int A = 5;
А = 10;

не должно работать?

Или вы полагаете, что строка ( с логической точки зрения ) должна чем-то отличаться от числа?


>> Код показывайте, а то у меня ничего такого не выдает.

А я показал. printf("f") ошибку дает, printf((char*)"f") нет.

Цитата:
Сообщение от waleri Посмотреть сообщение
Наличие приведения типа обычно признак проблемы.
Ну, я бы сказал, очень спорное мнение. Но в данном контексте не о том речь - просто странно, что после приведения к просто указателю функция параметр принимает. Я этого не могу объяснить (в хедере параметр описан как char const* const Format. Должен быть совместим с константами.
protoder вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Непонятки с видом инициализации строки. KAMLS Общие вопросы C/C++ 11 10.11.2018 09:04
Ошибка инициализации D6ist Общие вопросы Delphi 0 25.03.2018 17:16
Ошибка при инициализации MCI EvgeniyVaravko Мультимедиа в Delphi 8 26.11.2017 14:59
Ошибка инициализации переменной. Gdasar C++ Builder 11 12.11.2014 23:46
Ошибка при инициализации PrintDialog tavrocotaps Общие вопросы Delphi 2 25.12.2009 14:13