Устаревшее преобразование строкового литерала в 'char *'

У меня есть программа, которая объявляет такой массив строк:

char *colors[4] = {"red", "orange", "yellow", "blue"};

Но я получаю предупреждение компилятора выше. Он компилируется, но я бы предпочел использовать не устаревший способ (если он есть). Я пытался выяснить, что это значит, но не могу понять. Я слышал об использовании 'const' до того, как 'char' сработает, но было бы полезно, если бы кто-нибудь мог объяснить, что означает ошибка. Спасибо.


person Matt    schedule 10.03.2012    source источник


Ответы (3)


Строки, которые вы вводите: «red», «organge» и т. Д. Являются «буквальными», потому что они определены внутри самого программного кода (они не читаются непосредственно с диска, пользовательского ввода / стандартного ввода и т. Д.).

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

Объявление его как константы гарантирует, что вы никогда не попытаетесь писать в этот указатель, и такой ошибки времени выполнения можно избежать.

const char *colors[4] = {"red", "orange", "yellow", "blue"};

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

person d_inevitable    schedule 10.03.2012
comment
Я полагаю, что необходимая сигнатура типа будет char const *colors[4] (т.е. массив из четырех константных указателей). - person James Aylett; 11.03.2012
comment
@JamesAylett, нет, это const char *colors[4]. Массив из 4 указателей на константные данные. - person HolyBlackCat; 08.07.2014
comment
@HolyBlackCat: Разве это не одно и то же? - person szx; 08.07.2014
comment
@szx, я думаю, он неправильно написал: an array of four constant pointers это char * const colors[4]. char const *colors[4] - странный, но верный способ описания массива из 4 указателей на константные данные. - person HolyBlackCat; 08.07.2014
comment
«Константный указатель на данные» - это не то же самое, что указатель на константные данные. Один из них - указатель, который нельзя изменить, но его цель (данные) могут быть изменены. Другой - указатель, который можно изменить, но его целевые данные являются константными и не могут быть изменены. Обсуждение на codeguru. (Да, я знаю, что опаздываю на несколько лет, но это частая путаница). - person JRobert; 26.03.2016

"red", "orange", "yellow", "blue"

это постоянная строка. Создание неконстантного указателя на постоянную строку неверно, отсюда и предупреждение. В настоящий момент вы получаете предупреждение, но это должно быть ошибкой, поскольку оно устарело в C ++ 03 и запрещено в C ++ 11.

person BЈовић    schedule 10.03.2012

Все ответы верны.

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

foo ("bar");

будет показано такое же предупреждение. В этом случае вы можете:

1) Измените его так, как описано в первом ответе:

void foo (char[] str) { printf(str); }

const char param[] = "bar";
foo (param);

2) Рассмотрите возможность использования стандартной строки C ++, например:

void foo (std::string theParam) { std::cout << theParam; }

foo ("bar");

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

Если требуется Unicode, поддержка в C ++ «ужасна», как объяснено здесь < / а>. Этот вопрос дает вам некоторые подсказки (в основном: используйте библиотеку IBM ICU). Если у вас уже есть Qt в вашем проекте, QString также подойдет, и Gettext сделает то же самое.

person tiktak    schedule 08.07.2014
comment
В объявлении функции void foo (char[] str) { printf(str); } отсутствует константа, она должна быть void foo (const char[] str) { printf(str); }. Первый вызовет candidate function not viable: 1st argument ('const char *') would lose const qualifier ошибку. - person Aldo Utrera; 05.02.2015
comment
Я пробовал оба этих подхода. Компилятор предупреждал: invalid conversion from 'const char*' to 'char*'. - person Codes with Hammer; 06.02.2020