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

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

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

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

char *s = "constant string";

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

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

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

Ответ 1

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

Ответ 2

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

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

Объяснение:

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

Пример:

#include <iostream>

void print(char* ch);

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

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

Ответ 4

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

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

Ответ 5

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

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

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

Ответ 6

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

char *setf = tigetstr("setf");

:

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

Ответ 7

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

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

Затем вы можете позже...

#pragma GCC diagnostic pop

Ответ 8

Заменить

char *str = "hello";

с

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

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

foo("hello");

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

foo((char*) "hello");

Ответ 9

Вместо:

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

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

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

Ответ 10

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

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

Ответ 11

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

char str[] = "Test string";

или

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

Ответ 12

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

(char*) "test"

Ответ 13

Производится ли приведение типов с постоянной строкой в ​​указатель char i.e.

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

Ответ 14

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

char *str = "hello";

с:

std::string str ("hello");

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

str.compare("HALLO");

Ответ 15

  Я не понимаю, как применить ваше решение :( - kalmanIsAGameChanger

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

  

Original function: char StrContains(char *str, char *sfind)

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

  

Modified: char StrContains(const char *str, const char *sfind).

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

Ответ 16

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

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

Ответ 17

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

Ответ 18

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

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

putenv("DEBUG=1");

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

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

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

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

Ответ 19

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

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

Ответ 20

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

Пример:

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

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

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

const char* s="constant string";  

Ответ 21

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

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 }

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

Ответ 22

Ответ 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;
    }

Ответ 23

Объявление строки как const решит проблему:

char const*s = "constant string";

Ответ 24

PyTypeObject PyDict_Type=
{ ...

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

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

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

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

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