Come eliminare gli avvisi di "conversione deprecata dalla costante di stringa a" char* "in GCC?

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

  •  09-06-2019
  •  | 
  •  

Domanda

Quindi sto lavorando su una codebase estremamente ampia e recentemente aggiornato a gcc 4.3, che ora attiva questo avviso:

avvertimento:conversione deprecata dalla costante stringa a "char*"

Ovviamente, il modo corretto per risolvere questo problema è trovare ogni dichiarazione like

char *s = "constant string";

o chiamata di funzione come:

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

e realizzarli const char puntatori.Tuttavia, ciò significherebbe toccare almeno 564 file, che non è un compito che desidero eseguire in questo momento.Il problema in questo momento è che sto correndo -werror, quindi ho bisogno di un modo per soffocare questi avvertimenti.Come lo posso fare?

È stato utile?

Soluzione

Credo che passi -Wno-write-strings to gcc sopprimerà questo avviso.

Altri suggerimenti

Qualsiasi funzione a cui passi valori letterali stringa "I am a string literal" dovrebbe usare char const * come tipo invece di char*.

Se hai intenzione di aggiustare qualcosa, aggiustala bene.

Spiegazione:

Non è possibile utilizzare valori letterali stringa per inizializzare le stringhe che verranno modificate, perché sono di tipo const char*.Gettare via la consistenza per modificarle in seguito lo è comportamento indefinito, quindi devi copiare il tuo const char* stringhe char di char in allocato dinamicamente char* stringhe per modificarle.

Esempio:

#include <iostream>

void print(char* ch);

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

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

Dai un'occhiata a GCC Pragma diagnostico supporto e l'elenco dei -W opzioni di avviso (cambiato: nuovo collegamento alle opzioni di avviso).

Per gcc, puoi usare #pragma warning direttive come spiegato Qui.

Ho avuto un problema simile, l'ho risolto in questo modo:

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

È questo un modo appropriato per risolvere questo problema?Non ho accesso a foo adattarlo per accettare const char*, anche se sarebbe una soluzione migliore (perché foo non cambia m).

Se si tratta di una codebase attiva, potresti comunque voler aggiornare la codebase.Naturalmente, eseguire le modifiche manualmente non è fattibile, ma credo che questo problema possa essere risolto una volta per tutte con un unico sed comando.Non l'ho provato, però, quindi prendi quanto segue con le pinze.

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

Questo potrebbe non trovare tutti i posti (anche senza considerare le chiamate di funzione) ma allevierebbe il problema e consentirebbe di eseguire manualmente le poche modifiche rimanenti.

Non riesco a utilizzare l'opzione del compilatore.Quindi ho trasformato questo:

char *setf = tigetstr("setf");

a questa:

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

Ecco come farlo in linea in un file, quindi non devi modificare il tuo Makefile.

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

Potrai quindi più tardi...

#pragma GCC diagnostic pop

Sostituire

char *str = "hello";

con

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

o se stai chiamando in funzione:

foo("hello");

sostituiscilo con

foo((char*) "hello");

Invece di:

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

Funziona:

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

In C++, utilizzare il const_cast come sotto

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

Test string è const stringa.Quindi puoi risolvere in questo modo:

char str[] = "Test string";

O:

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

Perché non usare semplicemente il casting del tipo?

(char*) "test"

Esegui il typecasting dalla stringa costante al puntatore al carattere, ad es.

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

In C++, sostituisci:

char *str = "hello";

con:

std::string str ("hello");

E se vuoi fare un confronto:

str.compare("HALLO");

Non capisco come applicare la tua soluzione :( – kalmanIsAGameChanger

Lavorando con Arduino Sketch, avevo una funzione che causava i miei avvisi.

Funzione originale:char StrContains(char *str, char *sfind)

Per interrompere gli avvisi ho aggiunto il file cost davanti al carattere *str e al carattere *sfind.

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

Tutti gli avvertimenti sono scomparsi.

vedi questa situazione:

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

guarda il campo del nome, in gcc si compila senza preavviso, ma in g++ lo farà, non so perché.

È inoltre possibile creare una stringa scrivibile da una costante stringa chiamando strdup().

Ad esempio, questo codice genera un avviso:

putenv("DEBUG=1");

Tuttavia, il codice seguente non lo fa (crea una copia della stringa sull'heap prima di passarla a putenv):

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

In questo caso (e forse nella maggior parte degli altri) disattivare l'avviso è una cattiva idea: è lì per un motivo.L'altra alternativa (rendere tutte le stringhe scrivibili per impostazione predefinita) è potenzialmente inefficiente.

Ascolta cosa ti dice il compilatore!

usa semplicemente l'opzione -w per g++

esempio:

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

Ricorda che questo non evita la deprecazione, piuttosto impedisce la visualizzazione di messaggi di avviso sul terminale.

Ora, se vuoi davvero evitare la deprecazione, usa la parola chiave const come questa:

const char* s="constant string";  

Perché non usi il -Wno-deprecated opzione per ignorare i messaggi di avviso deprecati?

Il problema in questo momento è che sto utilizzando -Werror

Questo è il tuo vero problema, IMO.Puoi provare alcuni modi automatizzati per passare da (char *) a (const char *), ma ci metterei dei soldi non solo per farli funzionare.Dovrai coinvolgere un essere umano almeno per parte del lavoro.Per il breve termine, ignora semplicemente l'avviso (ma IMO lascialo attivo, altrimenti non verrà mai risolto) e rimuovi semplicemente -Werror.

Grazie a tutti per l'aiuto.Scegliendo di qua e di là arriva questa soluzione.Questo compila pulito.Non ho ancora testato il codice.Domani...Forse...

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 so, c'è solo 1 elemento nell'array timeServer.Ma potrebbe esserci di più.Il resto è stato commentato per ora per risparmiare memoria.

La risposta di BlackShift è molto utile e l'ho usata in questo modo:

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

guarda il campo del nome, in gcc si compila senza preavviso, ma in g++ lo farà, non so perché.

In gcc (Compiling C), -Wno-write-strings è attivo per impostazione predefinita.

In g++ (Compiling C++) -Wwrite-strings è attivo per impostazione predefinita

Ecco perché c'è un comportamento diverso.Per noi che utilizziamo le macro di Boost_python genera tali avvisi.Quindi usiamo -Wno-write-strings quando compiliamo C++ poiché usiamo sempre -Werror

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top