Veraltete C++-Konvertierung von Zeichenfolgenkonstanten in „char*“

Lesezeit: 7 Minuten

Veraltete C Konvertierung von Zeichenfolgenkonstanten in „char
mkamthan

Ich habe eine Klasse mit a private char str[256];

und dafür habe ich einen expliziten Konstruktor:

explicit myClass(const char *func)
{
    strcpy(str,func);
}

Ich nenne es so:

myClass obj("example");

Beim Kompilieren erhalte ich folgende Warnung:

veraltete Konvertierung von String-Konstante zu ‘char*’

Warum passiert dies?

  • Du solltest benutzen strncpy(str, func, 255) anstatt strcpy(str, func) für eine sicherere Kopie. Und dann vergessen Sie nicht, das ‘\0’ am Ende der Zeichenfolge hinzuzufügen, da strncpy es nicht hinzufügt.

    – Patrice Bernassola

    6. Oktober 2009 um 8:55 Uhr

  • Noch sicherer ist es zu sagen “strncpy(str, func, sizeof(str)); str[sizeof(str) – 1] = ‘\0’;”

    – Warren Young

    6. Oktober 2009 um 8:59 Uhr

  • Ich glaube nicht, dass das Obige die von Ihnen zitierte Warnung enthält, obwohl ich mir sicher bin, dass ein ziemlich ähnlicher Code dies tun würde. Um aussagekräftige Antworten zu erhalten, sollten Sie ein minimales, kompilierendes Beispiel posten, das die Warnung erzeugt.

    – sbi

    6. Oktober 2009 um 9:23 Uhr

  • @Patrice, Warren: Verwenden Sie strncpy nicht, es ist keine sicherere Version von strcpy. Verwenden (oder neu implementieren) strcpy_s.

    – Steve Jessop

    6. Oktober 2009 um 15:26 Uhr

  • Ich habe das Problem, es zeigt diese Probleme nur für einen -X86-Build und nicht für normale Solaris- oder ARM(Ziel)-Builds, also ignoriere ich das. Konnte immer noch keine Lösung finden, da normalerweise auch für meinen Beispielcode keine Warnung angezeigt wird. Danke euch allen!

    – mkamthan

    7. Oktober 2009 um 6:13 Uhr

1646928014 37 Veraltete C Konvertierung von Zeichenfolgenkonstanten in „char
Sellibitze

Dies ist eine Fehlermeldung, die Sie sehen, wenn Sie eine Situation wie die folgende haben:

char* pointer_to_nonconst = "string literal";

Warum? Nun, C und C++ unterscheiden sich im Typ des String-Literals. In C ist der Typ ein Array von char und in C++ ist es Konstante Array von Zeichen In jedem Fall dürfen Sie die Zeichen des String-Literals nicht ändern, daher ist die Konstante in C++ keine wirkliche Einschränkung, sondern eher eine Typsicherheitssache. Eine Umstellung von const char* zu char* ohne expliziten Cast ist aus Sicherheitsgründen generell nicht möglich. Aber für die Abwärtskompatibilität mit C erlaubt die Sprache C++ immer noch die Zuweisung eines String-Literals zu a char* und warnt Sie, dass diese Konvertierung veraltet ist.

Irgendwo fehlt also eine oder mehrere consts in Ihrem Programm auf const-Korrektheit. Aber der Code, den Sie uns gezeigt haben, ist nicht das Problem, da er diese Art von veralteter Konvertierung nicht durchführt. Die Warnung muss woanders hergekommen sein.

  • Angesichts der Ansicht und der Abstimmungen zu dieser Frage ist es bedauerlich, dass das OP niemals Code bereitgestellt hat, der das Problem tatsächlich demonstriert.

    – Shafik Yaghmour

    11. März 2015 um 19:23 Uhr

  • Sie können das Problem mit dem OP-Code reproduzieren, indem Sie die const von dem MyClass Konstruktor … dann können Sie es beheben, indem Sie die hinzufügen const zurück.

    – Theodor Murdock

    8. Januar 2019 um 18:27 Uhr

Veraltete C Konvertierung von Zeichenfolgenkonstanten in „char
fnieto – Fernando Nieto

Die Warnung:

veraltete Konvertierung von String-Konstante zu ‘char*’

ist gegeben, weil Sie irgendwo (nicht in dem von Ihnen geposteten Code) so etwas tun:

void foo(char* str);
foo("hello");

Das Problem ist, dass Sie versuchen, ein Zeichenfolgenliteral (mit type const char[]) zu char*.

Sie können a umwandeln const char[] zu const char* weil das Array auf den Zeiger zerfällt, aber was Sie tun, ist, eine veränderliche eine Konstante zu machen.

Diese Konvertierung ist wahrscheinlich für die C-Kompatibilität erlaubt und gibt Ihnen nur die erwähnte Warnung.

1646928016 571 Veraltete C Konvertierung von Zeichenfolgenkonstanten in „char
stätig

Als Antwort Nr. 2 von fnieto – Fernando Nieto beschreibt klar und richtig, dass diese Warnung gegeben wird, weil Sie irgendwo in Ihrem Code (nicht in dem von Ihnen geposteten Code) so etwas tun wie:

void foo(char* str);
foo("hello");

Wenn Sie Ihren Code jedoch auch warnungsfrei halten möchten, nehmen Sie einfach die entsprechende Änderung in Ihrem Code vor:

void foo(char* str);
foo((char *)"hello");

Das heißt, werfen Sie einfach die string konstant zu (char *).

  • Alternativ machen Sie die Funktion: void foo(const char* str)

    – Caprooja

    14. April 2014 um 16:28 Uhr

  • @Caprooja Ja, das Deklarieren des Parameters als “Zeiger auf eine Konstante” funktioniert auch in diesem Fall. Aber mit dieser Änderung kann der Benutzer den an der Adresse gespeicherten Wert nicht mehr ändern/neu zuweisen, indem er den ‘str’-Zeiger verwendet, was der Benutzer möglicherweise im Implementierungsteil tut. Das ist also etwas, worauf Sie achten sollten.

    – saktiw

    15. April 2014 um 7:37 Uhr


  • @sactiw Gibt es Gründe zu behalten void foo(char* str) wie es ist? Ich dachte, wir können nicht modifizieren str in foo Wie auch immer, sogar der Parameter wird als nicht konstant geschrieben.

    – kgf3JfUtW

    22. November 2016 um 20:21 Uhr

1646928017 21 Veraltete C Konvertierung von Zeichenfolgenkonstanten in „char
anilbey

Es gibt 3 Lösungen:

Lösung 1:

const char *x = "foo bar";

Lösung 2:

char *x = (char *)"foo bar";

Lösung 3:

char* x = (char*) malloc(strlen("foo bar")+1); // +1 for the terminator
strcpy(x,"foo bar");

Anstelle von Zeigern können auch Arrays verwendet werden, da ein Array bereits ein konstanter Zeiger ist.

Ein Grund für dieses Problem (der noch schwieriger zu erkennen ist als das Problem mit char* str = "some string" – was andere erklärt haben) ist, wenn Sie es verwenden constexpr.

constexpr char* str = "some string";

Es scheint, dass es sich ähnlich verhalten würde const char* strund würde daher keine Warnung auslösen, wie es zuvor der Fall war char*aber es verhält sich stattdessen wie char* const str.

Einzelheiten

Konstantenzeiger und Zeiger auf eine Konstante. Der Unterschied zwischen const char* strund char* const str lässt sich wie folgt erklären.

  1. const char* str : Deklarieren Sie str als Zeiger auf ein konstantes Zeichen. Das bedeutet, dass die Daten, auf die dieser Zeiger zeigt, konstant sind. Der Zeiger kann geändert werden, aber jeder Versuch, die Daten zu ändern, würde einen Kompilierungsfehler auslösen.
    1. str++ ; : GÜLTIG. Wir ändern den Zeiger und nicht die Daten, auf die gezeigt wird.
    2. *str="a"; : UNGÜLTIG. Wir versuchen, die Daten, auf die verwiesen wird, zu ändern.
  2. char* const str : Deklarieren Sie str als konstanten Zeiger auf char. Das bedeutet, dass der Punkt jetzt konstant ist, aber die Daten, auf die gezeigt wird, sind es auch nicht. Der Zeiger kann nicht geändert werden, aber wir können die Daten mithilfe des Zeigers ändern.
    1. str++ ; : UNGÜLTIG. Wir versuchen, die Zeigervariable zu ändern, die eine Konstante ist.
    2. *str="a"; : GÜLTIG. Wir versuchen, die Daten, auf die verwiesen wird, zu ändern. In unserem Fall führt dies nicht zu einem Kompilierungsfehler, sondern zu einem Laufzeit Fehler, da die Zeichenfolge höchstwahrscheinlich in einen schreibgeschützten Abschnitt der kompilierten Binärdatei aufgenommen wird. Diese Anweisung wäre sinnvoll, wenn wir Speicher dynamisch zugewiesen hätten, z. char* const str = new char[5];.
  3. const char* const str : Deklarieren Sie str als konstanten Zeiger auf ein konstantes Zeichen. In diesem Fall können wir weder den Zeiger noch die Daten, auf die gezeigt wird, ändern.
    1. str++ ; : UNGÜLTIG. Wir versuchen, die Zeigervariable zu ändern, die eine Konstante ist.
    2. *str="a"; : UNGÜLTIG. Wir versuchen, die Daten zu ändern, auf die dieser Zeiger zeigt, der ebenfalls konstant ist.

In meinem Fall war das Problem, dass ich erwartet hatte constexpr char* str sich verhalten als const char* strund nicht char* const strda es dem ersteren optisch näher kommt.

Auch die generierte Warnung für constexpr char* str = "some string" unterscheidet sich geringfügig von char* str = "some string".

  1. Compiler-Warnung für constexpr char* str = "some string": ISO C++11 does not allow conversion from string literal to 'char *const'
  2. Compiler-Warnung für char* str = "some string": ISO C++11 does not allow conversion from string literal to 'char *'.

Tipp

Sie können verwenden C Kauderwelsch ↔ Englisch Konverter umwandeln C Erklärungen in leicht verständliche englische Erklärungen umwandeln und umgekehrt. Das ist ein C einziges Werkzeug und unterstützt daher keine Dinge (wie constexpr), die exklusiv sind C++.

1646928018 146 Veraltete C Konvertierung von Zeichenfolgenkonstanten in „char
dan ionescu

Tatsächlich ist ein String-Konstantenliteral weder ein const char * noch ein char*, sondern ein char[]. Es ist ziemlich seltsam, aber in den C++-Spezifikationen niedergeschrieben; Wenn Sie es ändern, ist das Verhalten undefiniert, da der Compiler es möglicherweise im Codesegment speichert.

1646928018 283 Veraltete C Konvertierung von Zeichenfolgenkonstanten in „char
Alen Lee

Vielleicht kannst du das versuchen:

void foo(const char* str) 
{
    // Do something
}

foo("Hello")

Für mich geht das

988380cookie-checkVeraltete C++-Konvertierung von Zeichenfolgenkonstanten in „char*“

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy