Есть такой код:
const LPSTR str = "str";
const char* str2 = "str";
int main()
{
char* w = str;
char* w2 = str2; //error: cannot convert from 'const char *' to 'char *'
return 0;
}
Почему появляется такая ошибка понятно. Но почему такой ошибки нет строчкой выше, когда используется LPSTR? Ведь это только typedef char* LPSTR;
Потому что typedef - это не макрос, т.е. не текстовая подстановка. В
const LPSTR str = "str";
const уже относится к самому str, а не к указуемым данным. То есть это эквивалентно следующему объявлению
char *const str = "str";
Отличие от
const char* str2 = "str";
очевидно.
Поэтому и нет ошибки в char* w = str;.
Формально в современном С++
const LPSTR str = "str";
является некорректным кодом. Указатель на некостантный char нельзя просто так поставить указывать на строковый литерал.
для начала разберемся с типами переменных:
const указателя на char посредством строкового литерала. Наличие const слева может вводить в заблуждение, так как он применяется ко всему типу LPSTR, а не только к его левой части, то бишь к char. Поведение для С и С++ в этом случае различается.const LPSTR str = "str";
// аналогично
LPSTR const str = "str";
char * const str = "str";
const char посредством строкового литерала. Вот тут const применяется непосредственно к типу char. Ничего криминального.const char* str2 = "str";
// аналогично
char const * str2 = "str";
char const * const str2 = "str";
const LPCSTR str2 = "str";
LPCSTR const str2 = "str";
char посредством const указателя на char. Ничего криминального.char* w = str;
char посредством указателя на const char. Это ошибка как в С, так и в С++.char* w2 = str2;
Ответ для языка C:
В стандарте C89 и C99 строковые литералы имеют тип "массив char" (без const), соответственно строковой литерал можно использовать для инициализации переменной типа char *. Однако попытка модификации буфера, на который будет указывать в этом случае указатель приводит к неопределенному поведению.
Если код в вопросе собрать как С код, то наличие только одной ошибки будет корректно - переменную с типом char * нельзя инициализировать значением с типом const char *.
Ответ для языка С++:
В современном С++ строковые литералы имеют тип "массив const char", соответственно строковой литерал для инициализации переменной типа char * использовать нельзя. Строка const LPSTR str = "str"; должна вызывать ошибку, однако в Visual Studio старых версий по-умолчанию используется некомфорное поведение "как в С". Выключить его в VS2015 можно указав компилятору опцию /Zc:strictStrings-, в VS2017 опцию /permissive-.
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости