
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?

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 const
s 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.

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.

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 *)
.

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* str
und 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* str
und char* const str
lässt sich wie folgt erklären.
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.
str++ ;
: GÜLTIG. Wir ändern den Zeiger und nicht die Daten, auf die gezeigt wird.
*str="a";
: UNGÜLTIG. Wir versuchen, die Daten, auf die verwiesen wird, zu ändern.
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.
str++ ;
: UNGÜLTIG. Wir versuchen, die Zeigervariable zu ändern, die eine Konstante ist.
*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];
.
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.
str++ ;
: UNGÜLTIG. Wir versuchen, die Zeigervariable zu ändern, die eine Konstante ist.
*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* str
und nicht char* const str
da 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"
.
- Compiler-Warnung für
constexpr char* str = "some string"
: ISO C++11 does not allow conversion from string literal to 'char *const'
- 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++
.

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.

Alen Lee
Vielleicht kannst du das versuchen:
void foo(const char* str)
{
// Do something
}
foo("Hello")
Für mich geht das
9883800cookie-checkVeraltete C++-Konvertierung von Zeichenfolgenkonstanten in „char*“yes
Du solltest benutzen
strncpy(str, func, 255)
anstattstrcpy(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