Как избавиться от `устаревшего преобразования из строковой константы в ‘char *’ ‘предупреждения в GCC?

Поэтому я работаю над чрезвычайно большой базой кода и недавно обновлен до gcc 4.3, который теперь вызывает это предупреждение:

предупреждение: устаревшее преобразование из строковой константы в ‘char *’

Очевидно, что правильный способ исправить это – найти каждое объявление, подобное

char *s = "constant string"; 

или вызов функции:

 void foo(char *s); foo("constant string"); 

и сделать их указателями const char . Однако это будет означать касание 564 файлов, минимум, что не является задачей, которую я хочу выполнить в этот момент времени. Проблема прямо сейчас в том, что я запускаю с -werror , поэтому мне нужно как-то заглушить эти предупреждения. Как я могу это сделать?

Я считаю, что передача -Wno-write-strings в gcc будет подавлять это предупреждение.

Любые функции, в которые вы передаете строковые литералы "I am a string literal" должны использовать char const * в качестве типа вместо char* .

Если вы собираетесь что-то исправить, исправьте это правильно.

Объяснение:

Вы не можете использовать строковые литералы для инициализации строк, которые будут изменены, поскольку они имеют тип const char* . Отбрасывание константы для последующего изменения их – неопределенное поведение , поэтому вам нужно скопировать const char* char char в динамически выделенные строки char* для их изменения.

Пример:

 #include using namespace std; void print(char *); void print(const char *ch) { cout< 

Проверьте gcc’s Diagnostic Pragma support и список опций предупреждения -W (изменено: новая ссылка на опции предупреждения ).

Для gcc вы можете использовать директивы #pragma warning как описано здесь .

У меня была аналогичная проблема, я решил это так:

 #include  extern void foo(char* m); int main() { // warning: deprecated conversion from string constant to 'char*' //foo("Hello"); // no more warning char msg[] = "Hello"; foo(msg); } 

Является ли это подходящим способом решения этого? У меня нет доступа к foo чтобы адаптировать его для принятия const char* , хотя это было бы лучшим решением (поскольку foo не меняет m ).

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

 find . -exec sed -E -i .backup -n \ -e 's/char\s*\*\s*(\w+)\s*= "/char const* \1 = "/g' {} \; 

Это может не найти все места (даже не учитывая вызовы функций), но это облегчит проблему и позволит выполнить несколько оставшихся изменений вручную.

Я не могу использовать компилятор. Поэтому я обратил это:

 char *setf = tigetstr("setf"); 

к этому:

 char *setf = tigetstr((char *)"setf"); 

Вот как это сделать inline в файле, поэтому вам не нужно изменять свой Makefile.

 // gets rid of annoying "deprecated conversion from string constant blah blah" warning #pragma GCC diagnostic ignored "-Wwrite-strings" 

Вы можете позже …

 #pragma GCC diagnostic pop 

замещать

 char *str = "hello"; 

с

 char *str = (char*)"hello"; 

или если вы вызываете функцию:

 foo("hello"); 

замените это на

 foo((char*) "hello"); 

Вместо:

 void foo(char *s); foo("constant string"); 

Это работает:

 void foo(const char s[]); foo("constant string"); 

В C ++ используйте const_cast как const_cast ниже.

 char* str = const_cast("Test string"); 

Test string – const. Поэтому вы можете решить вот так:

 char str[] = "Test string"; 

или:

 const char* str = "Test string"; printf(str); 

Почему бы просто не использовать литье типа?

 (char*) "test" 

Применять типтирование с постоянной строки на указатель на указатель, т. Е.

 char *s = (char *) "constant string"; 

Вы также можете создать записываемую строку из строковой константы, вызвав strdup() .

Например, этот код генерирует предупреждение:

 putenv("DEBUG=1"); 

Однако следующий код не делает (он делает копию строки в куче, прежде чем передать ее в putenv ):

 putenv(strdup("DEBUG=1")); 

В этом случае (и, возможно, в большинстве других) выключение предупреждения – плохая идея – это не так. Другая альтернатива (делая все строки, доступные для записи по умолчанию) потенциально неэффективна.

Слушайте, что компилятор вам говорит!

см. эту ситуацию:

 typedef struct tagPyTypeObject { PyObject_HEAD; char *name; PrintFun print; AddFun add; HashFun hash; } PyTypeObject; PyTypeObject PyDict_Type= { PyObject_HEAD_INIT(&PyType_Type), "dict", dict_print, 0, 0 }; 

смотрите поле имени, в gcc он компилируется без предупреждения, но в g ++ это будет, я не знаю почему.

Я не понимаю, как применить ваше решение 🙁 – kalmanIsAGameChanger

Работая с Arduino Sketch, у меня была функция, вызывающая мои предупреждения.

Исходная функция: char StrContains (char * str, char * sfind)

Чтобы остановить предупреждения, я добавил const перед char * str и char * sfind.

Изменено: char StrContains (const char * str, const char * sfind).

Все предупреждения ушли.

просто используйте параметр -w для g ++

пример:

g ++ -w -o simple.o simple.cpp -lpthread

Помните, что это не исключает устаревания, а предотвращает показ предупреждающего сообщения на терминале.

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

 const char* s="constant string"; 

Почему вы не используете параметр -Wno-deprecated для игнорирования устаревших предупреждающих сообщений?

Ответ BlackShift очень полезен, и я использовал его так:

 extern string execute(char* cmd) { FILE* pipe = popen(cmd, "r"); if (!pipe) return "ERROR"; char buffer[256]; std::string result = " "; while(!feof(pipe)) { if(fgets(buffer, 128, pipe) != NULL) result += buffer; } pclose(pipe); return result; } int main(){ char cmd[]="grep -A1 'xml' out1.txt | grep read|awk -F'=' 'BEGIN{sum=0}{sum=sum+$NF}END{print sum}'"; string result=execute(cmd); int numOfBytes= atoi(result.c_str()); cout<<"Number of bytes = "< 

Проблема прямо сейчас в том, что я работаю с -Werror

Это ваша настоящая проблема, ИМО. Вы можете попробовать несколько автоматических способов перехода от (char *) к (const char *), но я бы поместил на них деньги не просто. Вам нужно будет вовлечь человека, по крайней мере, в часть работы. В краткосрочной перспективе просто проигнорируйте предупреждение (но IMO оставит его, или он никогда не будет исправлен) и просто удалите -Werror.

Спасибо всем за помощь. Выбор отсюда и там приходит это решение. Это компилируется. Еще не проверял код. Может быть, завтра…

 const char * timeServer[] = { "pool.ntp.org" }; // 0 - Worldwide #define WHICH_NTP 0 // Which NTP server name to use. ... sendNTPpacket(const_cast(timeServer[WHICH_NTP])); // send an NTP packet to a server ... void sendNTPpacket(char* address) { code } 

Я знаю, в массиве timeServer есть только 1 элемент. Но может быть и больше. Остальные были закомментированы, чтобы сохранить память.

В C ++ замените:

 char *str = "hello"; 

с:

 std::string str ("hello"); 

И если вы хотите сравнить его:

 str.compare("HALLO"); 
 PyTypeObject PyDict_Type= { ... PyTypeObject PyDict_Type= { PyObject_HEAD_INIT(&PyType_Type), "dict", dict_print, 0, 0 }; 

смотрите поле имени, в gcc он компилируется без предупреждения, но в g ++ это будет, я не знаю почему.

в gcc (Compiling C) , -Wno-write-strings активна по умолчанию.

в g++ (Compiling C++) -Wwrite-strings активна по умолчанию

Вот почему существует другое поведение. Для нас использование макросов Boost_python генерирует такие предупреждения. Поэтому мы используем -Wno-write-strings при компиляции C ++, поскольку мы всегда используем -Werror

  • Согласованность hashCode () в строке Java
  • Как обрезать пробелы из переменной Bash?
  • Проблема сортировки строк в C #
  • Когда мы должны использовать метод intern для String для строковых литералов
  • strcmp на строке, прочитанной с помощью fgets
  • Создание фабричного метода в Java, который не полагается на if-else
  • Помещение символа в строку java для каждого символа N
  • C оптимизация строковых литералов
  • Как удалить ведущие нули из буквенно-цифрового текста?
  • Понимание логики в CaseInsensitiveComparator
  • C ++ Преобразование строки (или char *) в wstring (или wchar_t *)
  • Давайте будем гением компьютера.