Der C ++ 11-Standard (ISO / IEC 14882: 2011) lautet § C.1.1
:
char* p = "abc"; // valid in C, invalid in C++
Für C ++ ist es in Ordnung, da ein Zeiger auf ein String-Literal schädlich ist, da jeder Versuch, es zu ändern, zu einem Absturz führt. Aber warum ist es in C gültig?
Das C ++ 11 sagt auch:
char* p = (char*)"abc"; // OK: cast added
Das heißt, wenn eine Besetzung zur ersten Anweisung hinzugefügt wird, wird sie gültig.
Warum macht das Casting die zweite Anweisung in C ++ gültig und wie unterscheidet sie sich von der ersten? Ist es nicht immer noch schädlich? Wenn dies der Fall ist, warum hat der Standard dann gesagt, dass es in Ordnung ist?
char[]
hat. Der zweite ist eineconst_cast
Verkleidung.OK
.const
, also waren sie es notwendigerweise nichtconst
.Antworten:
Bis C ++ 03 war Ihr erstes Beispiel gültig, verwendete jedoch eine veraltete implizite Konvertierung. Ein Zeichenfolgenliteral sollte als typisiert behandelt werden
char const *
, da Sie seinen Inhalt nicht ändern können (ohne undefiniertes Verhalten zu verursachen).Ab C ++ 11 wurde die implizite Konvertierung, die veraltet war, offiziell entfernt, sodass davon abhängiger Code (wie in Ihrem ersten Beispiel) nicht mehr kompiliert werden sollte.
Sie haben einen Weg gefunden, wie der Code kompiliert werden kann: Obwohl die implizite Konvertierung entfernt wurde, funktioniert eine explizite Konvertierung weiterhin, sodass Sie eine Besetzung hinzufügen können. Ich würde dies jedoch nicht als "Korrektur" des Codes betrachten.
Um den Code wirklich zu korrigieren, muss der Zeigertyp auf den richtigen Typ geändert werden:
Warum es in C ++ erlaubt war (und immer noch in C ist): einfach, weil es eine Menge vorhandenen Codes gibt, der von dieser impliziten Konvertierung abhängt, und das Brechen dieses Codes (zumindest ohne offizielle Warnung) schien den Standardausschüssen anscheinend zu gefallen eine schlechte Idee.
quelle
char const *p = "abc";
„gültig und sicher in sowohl C und C ++“, nicht „gültig und sicher in beiden C oder C ++“.Es ist aus historischen Gründen in C gültig. C traditionell festgelegt , dass der Typ eines Stringliteral war
char *
nichtconst char *
, obwohl sie es qualifiziert , indem er sagte , dass Sie nicht wirklich , es zu ändern erlaubt.Wenn Sie eine Besetzung verwenden, teilen Sie dem Compiler im Wesentlichen mit, dass Sie besser als die Standardregeln für die Typübereinstimmung Bescheid wissen, und die Zuweisung wird dadurch in Ordnung.
quelle
char[N]
und wurde geändert inconst char[N]
. Es sind Größeninformationen beigefügt.char[N]
aber nichtchar*
zB"abc"
istchar[4]
Sie können auch strdup verwenden :
quelle