Как избавиться от ‘deprecated conversion from string constant to ' char*’ warnings в GCC?

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

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

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

char *s = "constant string";

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

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

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

23 ответов


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


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

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

объяснение:

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

пример:

#include <iostream>

void print(char* ch);

void print(const char* ch) {
    std::cout<<ch;
}

int main() {
    print("Hello");
    return 0;
}

Проверьте gcc в Диагностический Прагма поддержка, и список - W параметры предупреждения (изменен: новая ссылка на варианты предупреждения).

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


у меня была похожая проблема, я решил ее так:

#include <string.h>

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 адаптировать его к accept const char*, хотя это было бы лучшим решением (потому что foo не меняет m).


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


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

char *setf = tigetstr("setf");

для этого:

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

вот как это сделать встроенным в файл, поэтому вам не нужно изменять свой 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 Как ниже

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

Test string является строкой const. Таким образом, вы можете решить так:

char str[] = "Test string";

или:

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

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

(char*) "test"

сделайте типизацию из постоянной строки в указатель char, т. е.

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++ это будет, я не знаю почему.


В C++, Заменить:

char *str = "hello";

С:

std::string str ("hello");

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

str.compare("HALLO");

Я не понимаю, как применить ваше решение: (- 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++ и-З -О простой.o простой.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 = "<<numOfBytes<<endl;
            return 0;
    }

проблема сейчас в том, что я бегу с-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<char*>(timeServer[WHICH_NTP])); // send an NTP packet to a server
...
void sendNTPpacket(char* address) { code }

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


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-строки активны по умолчанию

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