¿Cómo deshacerse de las advertencias de "conversión obsoleta de constante de cadena a "char*" en GCC?

StackOverflow https://stackoverflow.com/questions/59670

  •  09-06-2019
  •  | 
  •  

Pregunta

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

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

Obviamente, la forma correcta de solucionar este problema es encontrar cada declaración como

char *s = "constant string";

o llamada de 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 mismo es que estoy corriendo con -werror, entonces necesito alguna forma de sofocar estas advertencias.¿Cómo puedo hacer eso?

¿Fue útil?

Solución

creo que pasando -Wno-write-strings a gcc suprimirá esta advertencia.

Otros consejos

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

Si vas a arreglar algo, hazlo bien.

Explicación:

No puede utilizar cadenas literales para inicializar cadenas que serán modificadas, porque son de tipo const char*.Desechar las constancias para luego modificarlas es comportamiento indefinido, entonces tienes que copiar tu const char* instrumentos de cuerda char por char en asignado dinámicamente char* cadenas para poder modificarlas.

Ejemplo:

#include <iostream>

void print(char* ch);

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

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

Echa un vistazo a gcc Pragma Diagnóstico soporte y la lista de -W opciones de advertencia (cambió: nuevo enlace a opciones de advertencia).

Para gcc, puedes usar #pragma warning directivas como explicadas aquí.

Tuve un problema similar, lo resolví así:

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

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

Si se trata de una base de código activa, es posible que aún desee actualizar la base de código.Por supuesto, realizar los cambios manualmente no es factible pero creo que este problema podría solucionarse de una vez por todas con un solo sed dominio.Sin embargo, no lo he probado, así que tómate lo siguiente con cautela.

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 permitiría realizar los pocos cambios restantes manualmente.

No puedo usar el modificador del compilador.Entonces 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 Makefile.

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

Luego podrás más tarde...

#pragma GCC diagnostic pop

Reemplazar

char *str = "hello";

con

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

o si estás llamando a la 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++, use el const_cast como abajo

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

Test string es una cadena constante.Entonces puedes resolver así:

char str[] = "Test string";

o:

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

¿Por qué no utilizar simplemente la conversión de tipos?

(char*) "test"

Encasille desde una cadena constante hasta un puntero de carácter, es decir,

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

En C++, reemplace:

char *str = "hello";

con:

std::string str ("hello");

Y si quieres compararlo:

str.compare("HALLO");

No entiendo cómo aplicar tu solución :( – kalmanIsAGameChanger

Al trabajar con Arduino Sketch, tenía una función que provocaba mis advertencias.

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

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

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

Todas las advertencias desaparecieron.

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

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

También puede crear una cadena grabable a partir de una constante de cadena llamando 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 pasarla a putenv):

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

En este caso (y quizás en la mayoría de los demás), desactivar la advertencia es una mala idea: está ahí por una razón.La otra alternativa (hacer que todas las cadenas se puedan escribir de forma predeterminada) es potencialmente ineficiente.

¡Escuche lo que le dice el compilador!

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

ejemplo:

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

Recuerde que esto no evita la obsolescencia, sino que evita mostrar mensajes de advertencia en el terminal.

Ahora, si realmente desea evitar la desaprobación, utilice la palabra clave const como esta:

const char* s="constant string";  

¿Por qué no usas el -Wno-deprecated ¿Opción para ignorar los mensajes de advertencia obsoletos?

El problema ahora es que estoy ejecutando -Werror

Este es tu verdadero problema, en mi opinión.Puede probar algunas formas automatizadas de pasar de (char *) a (const char *), pero yo apostaría dinero por que no solo funcionen.Tendrás que tener un humano involucrado para al menos parte del trabajo.A corto plazo, simplemente ignore la advertencia (pero, en mi opinión, déjela activada o nunca se solucionará) y simplemente elimine el error -Werror.

Gracias por toda la ayuda.Escogiendo de aquí y de allá surge esta solución.Esto se compila limpio.Aún no he probado el código.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<char*>(timeServer[WHICH_NTP])); // send an NTP packet to a server
...
void sendNTPpacket(char* address) { code }

Lo sé, sólo hay 1 elemento en la matriz timeServer.Pero podría haber más.El resto fueron comentados por ahora para ahorrar memoria.

La respuesta de BlackShift es muy útil y la usé así:

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;
    }
PyTypeObject PyDict_Type=
{ ...

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

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

en gcc (Compiling C), -Wno-write-strings está activo de forma predeterminada.

en g++ (Compiling C++) -Wwrite-strings está activo por defecto

Por eso hay un comportamiento diferente.Para nosotros usando macros de Boost_python genera tales advertencias.Entonces usamos -Wno-write-strings al compilar C++ ya que siempre usamos -Werror

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top