Ich arbeite also an einer außerordentlich großen Codebasis und habe kürzlich ein Upgrade auf gcc 4.3 durchgeführt, das jetzt diese Warnung auslöst:
Warnung: Veraltete Konvertierung von Zeichenfolgenkonstante in 'char *'
Offensichtlich ist der richtige Weg, dies zu beheben, jede Erklärung wie zu 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, mindestens 564 Dateien zu berühren, was zu diesem Zeitpunkt keine Aufgabe ist, die ich ausführen möchte. Das Problem im Moment ist, dass ich mit laufe -werror
, also brauche ich eine Möglichkeit, diese Warnungen zu unterdrücken. Wie kann ich das machen?
Antworten:
Ich glaube, dass die Übergabe
-Wno-write-strings
an gcc diese Warnung unterdrücken wird.quelle
#pragma GCC diagnostic ignored "-Wwrite-strings"
.Alle Funktionen, an die Sie Zeichenfolgenliterale übergeben,
"I am a string literal"
solltenchar const *
anstelle von verwendet werdenchar*
.Wenn Sie etwas reparieren wollen, reparieren Sie es richtig.
Erläuterung:
Sie können keine Zeichenfolgenliterale verwenden, um Zeichenfolgen zu initialisieren, die geändert werden, da sie vom Typ sind
const char*
. Wegwerfen die Konstantheit , um sie dann zu ändern ist nicht definiertes Verhalten , so dass Sie Ihre kopierenconst char*
Stringschar
vonchar
in dynamisch zugewiesenenchar*
Strings , um sie zu ändern.Beispiel:
quelle
char *
.const char *
In diesem Fall habe ich normalerweise gegossen.char*
auch für Zeichenfolgen, die nicht geändert werden. Wenn Sie einen Parameter als nehmenchar const*
und ihn an eine Standardfunktion übergeben, die einen nimmt, werdenchar*
Sie das treffen. Wenn die Bibliotheksfunktion die Zeichenfolge nicht manipuliert, können Sie die Zeichenfolge wegwerfenconst
.Ich hatte ein ähnliches Problem, ich habe es so gelöst:
Ist dies ein geeigneter Weg, um dies zu lösen? Ich habe keinen Zugriff darauf
foo
, um es anzupassenconst char*
, obwohl das eine bessere Lösung wäre (weilfoo
sich nichts ändertm
).quelle
char **
in sucht,PyArg_ParseTupleAndKeywords
mache ich so etwas:static char kw[][16] = {"mode", "name", "ip", "port"}; static char * kwlist[] = {kw[0], kw[1], kw[2], kw[3], NULL};
Schauen Sie sich die Unterstützung von gcc für Diagnostic Pragma und die Liste der -W-Warnoptionen an (geändert: neuer Link zu Warnoptionen ).
Für gcc können Sie
#pragma warning
Anweisungen verwenden, wie hier erläutert .quelle
Wenn es sich um eine aktive Codebasis handelt, möchten Sie die Codebasis möglicherweise trotzdem aktualisieren. Natürlich ist es nicht möglich, die Änderungen manuell durchzuführen, aber ich glaube, dass dieses Problem ein für alle Mal mit einem einzigen
sed
Befehl gelöst werden kann . Ich habe es jedoch nicht ausprobiert, also nimm das Folgende mit einem Körnchen Salz.Dies findet möglicherweise nicht alle Stellen (auch wenn Funktionsaufrufe nicht berücksichtigt werden), lindert jedoch das Problem und ermöglicht es, die wenigen verbleibenden Änderungen manuell durchzuführen.
quelle
Ich kann den Compiler-Schalter nicht verwenden. Also habe ich das gedreht:
dazu:
quelle
Hier erfahren Sie, wie Sie dies in einer Datei inline tun, damit Sie Ihr Makefile nicht ändern müssen.
Sie können dann später ...
quelle
Ersetzen
mit
oder wenn Sie die Funktion aufrufen:
Ersetzen Sie dies durch
quelle
Anstatt:
Das funktioniert:
quelle
Verwenden Sie in C ++
const_cast
wie folgtquelle
Test string
ist const string. So können Sie lösen:oder:
quelle
Warum nicht einfach Typ Casting verwenden?
quelle
Führen Sie eine Typumwandlung von einer konstanten Zeichenfolge zu einem Zeichenzeiger durch, z
quelle
Ersetzen Sie in C ++:
mit:
Und wenn Sie es vergleichen wollen:
quelle
Bei der Arbeit mit Arduino Sketch hatte ich eine Funktion, die meine Warnungen verursachte.
Um die Warnungen zu stoppen, habe ich die Konstante vor dem Zeichen und dem Zeichen hinzugefügt.
Alle Warnungen gingen weg.
quelle
siehe diese Situation:
Beobachten Sie das Namensfeld, in gcc wird es ohne Vorwarnung kompiliert, aber in g ++ wird es, ich weiß nicht warum.
quelle
Sie können auch eine beschreibbare Zeichenfolge aus einer Zeichenfolgenkonstante erstellen, indem Sie aufrufen
strdup()
.Dieser Code generiert beispielsweise eine Warnung:
Der folgende Code funktioniert jedoch nicht (er erstellt eine Kopie der Zeichenfolge auf dem Heap, bevor er an übergeben wird
putenv
):In diesem Fall (und vielleicht in den meisten anderen Fällen) ist es eine schlechte Idee, die Warnung auszuschalten - sie hat einen Grund. Die andere Alternative (standardmäßig alle Zeichenfolgen beschreibbar zu machen) ist möglicherweise ineffizient.
Hören Sie, was der Compiler Ihnen sagt!
quelle
putenv()
ist voller Probleme - es ist keine gute Wahl für ein Beispiel (zumindest nicht ohne viel mehr Diskussion darüber, wasputenv()
tut, als in dieser Antwort enthalten ist). Es ist eine ganz separate Diskussion. (Beachten Sie, dass die POSIX-Spezifikation für das Verhalten vonputenv()
problematisch ist, basierend auf den Legacy-Implementierungen von vor der Definition von POSIX.) IIRC, es gab einen Fehler in einer kürzlich (in diesem Jahrtausend) veröffentlichten Version der GNU C Library, der sich aufputenv()
Verhaltensänderungen bezog. und zurück geändert werden.)Verwenden Sie einfach die Option -w für g ++
Beispiel:
g ++ -w -o simple.o simple.cpp -lpthread
Denken Sie daran, dass dies nicht die Ablehnung verhindert, sondern das Anzeigen einer Warnmeldung auf dem Terminal verhindert.
Wenn Sie nun wirklich die Ablehnung vermeiden möchten, verwenden Sie das Schlüsselwort const wie folgt:
quelle
Warum verwenden Sie die
-Wno-deprecated
Option nicht, um veraltete Warnmeldungen zu ignorieren?quelle
Das ist dein eigentliches Problem, IMO. Sie können einige automatisierte Methoden ausprobieren, um von (char *) zu (const char *) zu wechseln, aber ich würde Geld in sie stecken, nicht nur um zu funktionieren. Für mindestens einen Teil der Arbeit muss ein Mensch beteiligt sein. Ignorieren Sie kurzfristig einfach die Warnung (aber IMO lässt sie eingeschaltet, sonst wird sie nie behoben) und entfernen Sie einfach den Fehler.
quelle
Vielen Dank für die Hilfe. Von hier und da kommt diese Lösung. Dies kompiliert sauber. Habe den Code noch nicht getestet. Vielleicht morgen...
Ich weiß, es gibt nur 1 Element im timeServer-Array. Aber es könnte noch mehr geben. Der Rest wurde vorerst auskommentiert, um Speicherplatz zu sparen.
quelle
Beobachten Sie das Namensfeld, in gcc wird es ohne Vorwarnung kompiliert, 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 aktivDeshalb gibt es ein anderes Verhalten. Für uns erzeugt die Verwendung von Makros von
Boost_python
solche Warnungen. Also verwenden wir-Wno-write-strings
beim Kompilieren von C ++, da wir immer verwenden-Werror
quelle
Deklarieren Sie einen String
const
, um das Problem zu lösen:quelle