Wie loswerden `veraltete Konvertierung von String-Konstante zu‚char *‘` Warnungen in GCC?

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

  •  09-06-2019
  •  | 
  •  

Frage

Also habe ich auf einen sehr großen Code-Basis gerade arbeite, und vor kurzem ein Upgrade 4.3 auf gcc, die jetzt diese Warnung auslöst:

  

Warnung: veraltet Konvertierung von String-Konstante zu ‚char *‘

Offensichtlich ist der richtige Weg, dies zu beheben, ist jede Erklärung wie

finden
char *s = "constant string";

oder Funktionsaufruf wie:

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

und machen sie const char Zeiger. Dies würde jedoch bedeuten, berührend 564 Dateien, Minimum, das nicht eine Aufgabe ist, ich möchte an dieser Stelle in der Zeit auszuführen. Das Problem ist im Moment, dass ich mit -werror renne, so brauche ich eine Möglichkeit, diese Warnungen zu ersticken. Wie kann ich das tun?

War es hilfreich?

Lösung

Ich glaube, vorbei -Wno-write-strings zu gcc wird diese Warnung unterdrücken.

Andere Tipps

Alle Funktionen, in denen übergeben Sie Stringliterale "I am a string literal" char const * als Typ statt char* verwenden sollte.

Wenn Sie vorhaben, etwas zu reparieren, reparieren es richtig.

Erklärung:

Sie können nicht Zeichenfolgenliterale verwenden, um Strings zu initialisieren, die geändert werden, weil sie vom Typ const char* sind. Gießen der Konstantheit weg später ändern sie ist undefiniertes Verhalten , so dass Sie von const char* in dynamisch zugewiesenen char Strings, um sie zu ändern char Ihre char* Strings zu kopieren.

Beispiel:

#include <iostream>

void print(char* ch);

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

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

Sehen Sie sich gcc Diagnose Pragma Unterstützung, und die Liste der -W Warnung Optionen (geändert: neuer Link Warnoptionen ).

Für gcc, können Sie #pragma warning Richtlinien verwenden wie erklärt hier .

Ich hatte ein ähnliches Problem, ich löste es wie folgt aus:

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

Ist dies ein geeigneter Weg, um dies zu lösen? Ich haben keinen Zugang zu foo es anzupassen const char* zu akzeptieren, obwohl das eine bessere Lösung wäre (weil foo m ändert sich nicht).

Wenn es eine aktive Codebasis ist, können Sie immer noch wollen die Code-Basis zu aktualisieren. Natürlich ist die Änderungen manuell durchführt nicht machbar, aber ich glaube, dass dieses Problem einmal gelöst werden kann und für alle durch einen einzigen Befehl sed. Ich habe nicht versucht es, obwohl, so nehmen Sie die folgenden mit einem Körnchen Salz.

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

Dies könnte nicht alle Orte finden (auch nicht Funktion Anrufe unter Berücksichtigung), aber es würde das Problem lindern und machen es möglich, die wenigen verbleibenden Änderungen manuell durchführen.

Ich kann nicht den Compiler-Schalter verwenden. So habe ich gedreht dies:

char *setf = tigetstr("setf");

folgt aus:

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

Hier ist, wie es inline in einer Datei zu tun, so müssen Sie Ihre Makefile nicht ändern.

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

Sie können dann später ...

#pragma GCC diagnostic pop

Ersetzen

char *str = "hello";

mit

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

oder wenn Sie in Funktion aufrufen:

foo("hello");

ersetzen diese mit

foo((char*) "hello");

Statt:

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

Das funktioniert:

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

In C ++, verwenden Sie die const_cast als wie unter

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

Test string ist const String. So können Sie wie folgt lösen:

char str[] = "Test string";

oder:

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

Warum nicht einfach type casting verwenden?

(char*) "test"

typecasting von konstantem String Sie Zeiger d.h verkohlen.

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

In C ++ ersetzen:

char *str = "hello";

mit:

std::string str ("hello");

Und wenn Sie wollen, dass es vergleichen:

str.compare("HALLO");
  

Ich verstehe nicht, wie Sie Ihre Lösung anzuwenden :( - kalmanIsAGameChanger

Arbeiten mit Arduino Sketch, ich hatte eine Funktion meine Warnungen verursacht.

  
    

Original-Funktion: char StrContains (char * str, char * sfind)

  

Um die Warnungen zu stoppen Ich habe die const vor dem char * str und dem char * sfind.

  
    

Geändert:. Char StrContains (const char * str, const char * sfind)

  

Alle Warnungen ging.

siehe

diese Situation:

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

sehen das Namensfeld, in gcc es ohne Warnung kompilieren, aber in g ++ wird es, ich weiß nicht, warum.

Sie können auch einen beschreibbaren String aus einem String-Konstante durch den Aufruf strdup() erstellen.

Zum Beispiel dieser Code eine Warnung aus:

putenv("DEBUG=1");

Allerdings ist der folgende Code nicht (es wird eine Kopie der Zeichenfolge auf dem Heap, bevor es putenv vorbei):

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

In diesem Fall (und vielleicht auch in den meisten anderen) die Warnung ausgeschaltet ist eine schlechte Idee - es ist es für einen Grund. Die andere Alternative (was alle Strings beschreibbar Standard) ist möglicherweise ineffizient.

Hören Sie, was der Compiler sagen Sie!

nur verwenden Option -w für g ++

Beispiel:

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

Denken Sie daran, diese deprecation nicht vermeiden sondern es verhindert auf dem Terminal Warnmeldung zeigt.

Nun, wenn Sie wirklich wollen, deprecation Verwendung const Schlüsselwort wie dies zu vermeiden:

const char* s="constant string";  

Warum nutzen Sie nicht die -Wno-deprecated Option veraltet Warnmeldungen zu ignorieren?

  

Das Problem ist im Moment, dass ich mit Werror renne

Das ist Ihr eigentliches Problem, IMO. Sie können einige automatisierte Möglichkeiten der Bewegung von (char *) versuchen (const char *), aber ich würde auf sie setzen Geld nicht nur zu arbeiten. Sie haben einen Menschen für mindestens einen Teil der Arbeit beteiligt haben. Für die kurzfristige, einfach ignorieren die Warnung (aber es IMO auf verlassen, oder es wird nie repariert) und nur die Werror entfernen.

Danke, alle, für die Hilfe. Pflücken von hier und dort kommt diese Lösung. Dies kompiliert sauber. Haben Sie nicht den Code noch nicht getestet. Morgen ... vielleicht ...

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 }

Ich weiß, gibt es nur noch 1 Artikel in dem Zeitserver-Array. Aber es könnte mehr sein. Der Rest wurde für jetzt auf Kommentar zu speichern.

BlackShift Antwort ist sehr hilfreich, und ich mag es:

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

sehen das Namensfeld, in gcc es ohne Warnung kompilieren, aber in g ++ wird es, ich weiß nicht, warum.

in gcc (Compiling C), -Wno-write-strings ist standardmäßig aktiv.

in g++ (Compiling C++) -Wwrite-strings ist standardmäßig aktiv

Aus diesem Grunde ist es ein anderes Verhalten. Für uns Makros von Boost_python Verwendung erzeugt solche Warnungen. So verwenden wir -Wno-write-strings wenn C ++ kompilieren, da wir immer -Werror verwenden

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top