¿Cómo deshacerse de la conversión obsoleta de la constante de cadena a las advertencias de ‘char *’ `en GCC?

Así que estoy trabajando en una base de código extremadamente grande, y recientemente actualicé a gcc 4.3, que ahora desencadena esta advertencia:

advertencia: conversión obsoleta de cadena constante a ‘char *’

Obviamente, la forma correcta de solucionar esto es encontrar cada statement como

char *s = "constant string"; 

o llamar a la función como:

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

y hacerlos const char punteros. Sin embargo, eso significaría tocar 564 archivos, como mínimo, lo cual no es una tarea que desee realizar en este momento. El problema ahora es que estoy corriendo con -werror , así que necesito alguna forma de reprimir estas advertencias. ¿Cómo puedo hacer eso?

Creo que pasar -Wno-write-strings a gcc suprimirá esta advertencia.

Cualquier función en la que pase literales de cadena "I am a string literal" debería usar char const * como tipo en lugar de char* .

Si vas a arreglar algo, corrígelo bien.

Explicación:

No puede usar cadenas literales para inicializar cadenas que serán modificadas, porque son de tipo const char* . Eliminar la constness para luego modificarlos es un comportamiento indefinido , por lo que debe copiar sus cadenas const char* cadenas char by char en cadenas char* dinámicamente asignadas para modificarlas.

Ejemplo:

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

Verifique el soporte de Diagnóstico Pragma de gcc y la lista de opciones de advertencia de -W (modificada: nuevo enlace a opciones de advertencia ).

Para gcc, puede usar #pragma warning directivas de #pragma warning como se explica aquí .

Tuve un problema similar, lo resolví así:

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

¿Es esta una forma apropiada de resolver esto? No tengo acceso a foo para adaptarlo para aceptar const char* , aunque sería una mejor solución (porque foo no cambia m ).

Si se trata de una base de código activa, es posible que desee actualizar la base de código. Por supuesto, realizar los cambios manualmente no es factible, pero creo que este problema podría resolverse de una vez por todas con un único comando sed . No lo he probado, así que tome lo siguiente con un grano de sal.

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

Es posible que esto no encuentre todos los lugares (incluso sin considerar las llamadas a funciones), pero aliviaría el problema y posibilitaría realizar los pocos cambios restantes manualmente.

No puedo usar el interruptor del comstackdor. Así que he convertido esto:

 char *setf = tigetstr("setf"); 

a esto:

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

Aquí se explica cómo hacerlo en línea en un archivo, para que no tenga que modificar su archivo Makefile.

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

Luego puedes …

 #pragma GCC diagnostic pop 

Reemplazar

 char *str = "hello"; 

con

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

o si está llamando en función:

 foo("hello"); 

reemplazar esto con

 foo((char*) "hello"); 

En lugar de:

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

Esto funciona:

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

En C ++, usa el const_cast como abajo

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

Test string es una cadena const. Entonces puedes resolverlo así:

 char str[] = "Test string"; 

o:

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

¿Por qué no usar el tipo de conversión?

 (char*) "test" 

Hacer encasillado de cadena constante a puntero char, es decir,

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

También puede crear una cadena escribible desde una constante de cadena llamando a strdup() .

Por ejemplo, este código genera una advertencia:

 putenv("DEBUG=1"); 

Sin embargo, el siguiente código no lo hace (hace una copia de la cadena en el montón antes de pasarlo a putenv ):

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

En este caso (y tal vez en la mayoría de los demás) apagar la advertencia es una mala idea, está ahí por una razón. La otra alternativa (hacer que todas las cadenas sean editables por defecto) es potencialmente ineficiente.

¡Escucha lo que el comstackdor te está diciendo!

ver esta situación:

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

mira el campo de nombre, en gcc comstack sin previo aviso, pero en g ++ lo hará, no sé por qué.

No entiendo cómo aplicar tu solución 🙁 – kalmanIsAGameChanger

Trabajando con Arduino Sketch, tenía una función que causaba mis advertencias.

Función original: char StrContains (char * str, char * sfind)

Para detener las advertencias agregué el const delante del char * str y el char * sfind.

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

Todas las advertencias se fueron.

solo use la opción -w para g ++

ejemplo:

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

Recuerde que esto no evita la depreciación, sino que evita que se muestre un mensaje de advertencia en la terminal.

Ahora, si realmente quiere evitar la depreciación, use la palabra clave const así:

 const char* s="constant string"; 

¿Por qué no usa la opción -Wno-deprecated para ignorar los mensajes de advertencia obsoletos?

La respuesta de BlackShift es muy útil, y la utilicé como:

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

El problema ahora es que estoy corriendo con -Werror

Este es tu problema real, OMI. Puede probar algunas formas automáticas de pasar de (char *) a (const char *) pero les pondré dinero, no solo trabajando. Tendrás que involucrar a un ser humano para al menos parte del trabajo. A corto plazo, simplemente ignore la advertencia (pero IMO lo deja encendido, o nunca se arreglará) y simplemente elimine el -Werror.

Gracias por toda la ayuda. Escogiendo de aquí y allá viene esta solución. Esto comstack limpio. No he probado el código todavía. Mañana tal vez…

 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 } 

Lo sé, solo hay 1 elemento en la matriz timeServer. Pero podría haber más. El rest se comentaron por ahora para ahorrar memoria.

En C ++, Reemplazar:

 char *str = "hello"; 

con:

 std::string str ("hello"); 

Y si quieres compararlo:

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

mira el campo de nombre, en gcc comstack sin previo aviso, pero en g ++ lo hará, no sé por qué.

en gcc (Compiling C) , -Wno-write-strings está activo por defecto.

en g++ (Compiling C++) comstackción de g++ (Compiling C++) -Wwrite-strings está activo de forma predeterminada

Es por eso que hay un comportamiento diferente. Para nosotros el uso de macros de Boost_python genera tales advertencias. Entonces usamos -Wno-write-strings al comstackr C ++ ya que siempre usamos -Werror