c++ - ¿Cómo deshacerse de `desaprobado la conversión de constantes de cadena a 'char *'` advertencias en GCC?




string (20)

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

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

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

char *s = "constant string";

o función llamada como:

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

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


Answers

La respuesta de BlackShift es muy útil, y la usé 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 = "<<numOfBytes<<endl;
            return 0;
    }

El problema en este momento es que estoy corriendo con -Werror

Este es tu verdadero problema, OMI. Puedes probar algunas formas automatizadas de moverte de (char *) a (const char *) pero yo les pondría dinero no solo trabajando. Tendrá que tener un humano involucrado por al menos parte del trabajo. Para el corto plazo, simplemente ignore la advertencia (pero IMO déjela activada, o nunca se solucionará) y simplemente elimine el error.


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

char str[] = "Test string";

o:

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

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é la constante frente a char * str y char * sfind.

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

Todas las advertencias se fueron.


Si es 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 solo comando sed . Sin embargo, no lo he probado, así que toma 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 permitiría realizar los pocos cambios restantes de forma manual.



En lugar de:

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

Esto funciona:

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

No puedo usar el interruptor del compilador. Así que he girado esto:

char *setf = tigetstr("setf");

a esto:

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

En C ++, Reemplace:

char *str = "hello";

con:

std::string str ("hello");

Y si quieres compararlo:

str.compare("HALLO");

En C ++, use el const_cast como abajo.

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

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


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"

Después puedes ...

#pragma GCC diagnostic pop

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

Si vas a arreglar algo, arréglalo bien.

Explicación:

No puede utilizar literales de cadena para inicializar cadenas que se modificarán, porque son de tipo const char* . Deshacerse de la constancia para modificarlas posteriormente es un comportamiento indefinido , por lo que debe copiar las cadenas de caracteres const char* char by char en las cadenas de caracteres char* asignadas dinámicamente para poder modificarlas.

Ejemplo:

#include <iostream>

void print(char* ch);

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

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

Reemplazar

char *str = "hello";

con

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

o si estás llamando en función:

foo("hello");

reemplazar esto con

foo((char*) "hello");

También puede crear una cadena de escritura 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 quizás en la mayoría de los otros), desactivar la advertencia es una mala idea, está ahí por una razón. La otra alternativa (hacer que todas las cadenas puedan escribirse por defecto) es potencialmente ineficiente.

¡Escucha lo que te dice el compilador!


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 del nombre, en gcc compile sin previo aviso, pero en g ++ lo hará, no sé por qué.


Hacer encasillamiento de cadena constante a puntero char, es decir

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

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


PyTypeObject PyDict_Type=
{ ...

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

mire el campo del nombre, en gcc compile sin previo aviso, pero en g ++ lo hará, no sé por qué.

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

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

Por eso hay un comportamiento diferente. Para nosotros, el uso de macros de Boost_python genera tales advertencias. Así que usamos -Wno-write-strings cuando compilamos C ++ ya que siempre usamos -Werror


GCC sólo está siguiendo el estándar . #877 : "Cada secuencia [...] de escape hexadecimal es la secuencia más larga de caracteres que puede constituir la secuencia de escape".





c++ string gcc