Como se livrar de `conversão obsoleta de constante de cadeia de caracteres para ‘char *’` avisos no GCC?

Por isso, estou trabalhando em uma base de código extremamente grande e recentemente atualizei para o gcc 4.3, que agora aciona esse aviso:

aviso: conversão reprovada da constante de string para ‘char *’

Obviamente, a maneira correta de corrigir isso é encontrar todas as declarações como

char *s = "constant string"; 

ou chamada de function como:

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

e torná-los pointers const char . No entanto, isso significaria tocar 564 arquivos, no mínimo, o que não é uma tarefa que desejo executar neste momento. O problema agora é que eu estou correndo com o -werror , então eu preciso de alguma maneira para sufocar esses avisos. Como eu posso fazer isso?

Eu acredito que passar -Wno-write-strings para o gcc irá suprimir este aviso.

Qualquer function na qual você passa literais de string "I am a string literal" deve usar char const * como o tipo em vez de char* .

Se você vai consertar alguma coisa, corrija bem.

Explicação:

Você não pode usar literais de string para inicializar strings que serão modificadas, porque elas são do tipo const char* . Afastando o constness para depois modificá-los é um comportamento indefinido , então você tem que copiar seu const char* char por char char* dinamicamente alocados para modificá-los.

Exemplo:

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

Confira o suporte do Diagnostic Pragma do gcc e a lista de opções de aviso -W (alterado: novo link para opções de aviso ).

Para o gcc, você pode usar diretivas de #pragma warning como explicado aqui .

Eu tive um problema parecido, resolvi assim:

 #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); } 

Esta é uma maneira apropriada de resolver isso? Eu não tenho access ao foo para adaptá-lo para aceitar const char* , apesar de que seria uma solução melhor (porque foo não muda m ).

Se for uma base de código ativo, talvez você ainda queira atualizar a base de código. É claro que realizar as alterações manualmente não é viável, mas acredito que esse problema poderia ser resolvido de uma vez por todas com um único comando sed . Eu não tentei, então, tome o seguinte com um grão de sal.

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

Isso pode não encontrar todos os locais (mesmo não considerando as chamadas de function), mas isso aliviaria o problema e possibilitaria a execução das poucas alterações restantes manualmente.

Eu não posso usar o switch de compilador. Então eu virei isso:

 char *setf = tigetstr("setf"); 

para isso:

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

Aqui está como fazer isso inline em um arquivo, assim você não precisa modificar seu Makefile.

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

Você pode então mais tarde …

 #pragma GCC diagnostic pop 

Substituir

 char *str = "hello"; 

com

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

ou se você está chamando em function:

 foo("hello"); 

substitua isso por

 foo((char*) "hello"); 

Ao invés de:

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

Isso funciona:

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

Em C ++, use o const_cast como abaixo

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

Test string é uma string const. Então você pode resolver assim:

 char str[] = "Test string"; 

ou:

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

Por que não usar apenas o tipo de casting?

 (char*) "test" 

Fazer typecasting de string constante para ponteiro char ou seja

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

Você também pode criar uma string gravável a partir de uma constante de string chamando strdup() .

Por exemplo, esse código gera um aviso:

 putenv("DEBUG=1"); 

No entanto, o seguinte código não faz (faz uma cópia da cadeia na pilha antes de passá-lo para putenv ):

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

Neste caso (e talvez na maioria dos outros) desligar o aviso é uma má ideia – está lá por uma razão. A outra alternativa (tornando todas as strings graváveis ​​por padrão) é potencialmente ineficiente.

Ouça o que o compilador está dizendo a você!

veja esta situação:

 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 }; 

observe o campo name, no gcc ele compila sem avisar, mas no g ++ ele vai, não sei porque.

Eu não entendo como aplicar sua solução 🙁 – kalmanIsAGameChanger

Trabalhando com o Arduino Sketch, eu tive uma function causando meus avisos.

Função original: char StrContains (char * str, char * sfind)

Para parar os avisos, adicionei o const na frente do char * str e do char * sfind.

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

Todos os avisos foram embora.

apenas use a opção -w para g ++

exemplo:

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

Lembre-se de que isso não evita a depreciação, mas evita a exibição de mensagens de aviso no terminal.

Agora, se você realmente quer evitar a depreciação, use a palavra-chave const assim:

 const char* s="constant string"; 

Por que você não usa a opção -Wno-deprecated para ignorar as mensagens de aviso descontinuadas?

A resposta do BlackShift é muito útil, e eu usei assim:

 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 = "< 

O problema agora é que eu estou correndo com -Werror

Este é o seu verdadeiro problema, IMO. Você pode tentar algumas formas automatizadas de mover (char *) para (const char *), mas eu colocaria dinheiro nelas não apenas trabalhando. Você terá que ter um humano envolvido pelo menos parte do trabalho. Para o curto prazo, apenas ignore o aviso (mas o IMO o deixa ligado ou ele nunca será consertado) e apenas remova o -Werror.

Obrigado a todos pela ajuda. Pegando aqui e ali vem essa solução. Isso compila limpo. Ainda não testei o código. Talvez amanhã…

 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 } 

Eu sei, há apenas 1 item na matriz timeServer. Mas poderia haver mais. O resto foi comentado por enquanto para economizar memory.

Em C ++, substitua:

 char *str = "hello"; 

com:

 std::string str ("hello"); 

E se você quiser comparar:

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

observe o campo name, no gcc ele compila sem avisar, mas no g ++ ele vai, não sei porque.

no gcc (Compiling C) , -Wno-write-strings está ativo por padrão.

em g++ (Compiling C++) -Strings -Wwrite está ativo por padrão

É por isso que há um comportamento diferente. Para nós, usar macros do Boost_python gera tais avisos. Portanto, usamos -Wno-write-strings ao compilar o C ++, pois sempre usamos -Werror