Ich habe eine Klasse mit einem private char str[256];
und dafür habe ich einen expliziten Konstruktor:
explicit myClass(const char *func)
{
strcpy(str,func);
}
Ich nenne es als:
myClass obj("example");
Wenn ich dies kompiliere, erhalte ich die folgende Warnung:
veraltete Konvertierung von String-Konstante in 'char *'
Warum passiert dies?
c++
string
explicit-constructor
mkamthan
quelle
quelle
strncpy(str, func, 255)
anstellestrcpy(str, func)
für eine sicherere Kopie verwenden. Und vergessen Sie dann nicht, das '\ 0' am Ende des Strings hinzuzufügen, da strncpy es nicht hinzufügt.Antworten:
Dies ist eine Fehlermeldung, die angezeigt wird, wenn Sie eine Situation wie die folgende haben:
Warum? Nun, C und C ++ unterscheiden sich in der Art des String-Literal. In C ist der Typ ein Array von char und in C ++ ein konstantes Array von char. In jedem Fall dürfen Sie die Zeichen des String-Literal nicht ändern, daher ist die Konstante in C ++ keine wirkliche Einschränkung, sondern eher eine Typensicherheitssache. Eine Umstellung von
const char*
aufchar*
ist aus Sicherheitsgründen in der Regel ohne explizite Besetzung nicht möglich. Aus Gründen der Abwärtskompatibilität mit C ermöglicht die Sprache C ++ jedoch weiterhin die Zuweisung eines Zeichenfolgenliteral zu achar*
und gibt eine Warnung aus, dass diese Konvertierung veraltet ist.Irgendwo fehlen Ihnen ein oder mehrere
const
s in Ihrem Programm, um die Richtigkeit der Konstanten zu gewährleisten. Der Code, den Sie uns gezeigt haben, ist jedoch nicht das Problem, da diese Art der veralteten Konvertierung nicht durchgeführt wird. Die Warnung muss von einem anderen Ort gekommen sein.quelle
const
aus demMyClass
Konstruktor löschen. Anschließend können Sie es beheben, indem Sie dieconst
Rückseite hinzufügen .Die Warnung:
wird gegeben, weil Sie irgendwo (nicht in dem Code, den Sie gepostet haben) etwas tun wie:
Das Problem ist, dass Sie versuchen, ein Zeichenfolgenliteral (mit Typ
const char[]
) in zu konvertierenchar*
.Sie können a in konvertieren
const char[]
,const char*
da das Array in den Zeiger zerfällt. Sie machen jedoch eine veränderbare Konstante.Diese Konvertierung ist wahrscheinlich aus Gründen der C-Kompatibilität zulässig und gibt nur die erwähnte Warnung aus.
quelle
Als Antwort nein. 2 von fnieto - Fernando Nieto beschreibt klar und korrekt, dass diese Warnung gegeben wird, weil Sie irgendwo in Ihrem Code (nicht in dem von Ihnen geposteten Code) etwas tun wie:
Wenn Sie Ihren Code jedoch auch vor Warnungen schützen möchten, nehmen Sie einfach entsprechende Änderungen an Ihrem Code vor:
Das heißt, wirf einfach die
string
Konstante auf(char *)
.quelle
void foo(char* str)
wie es ist? Ich dachte , wir können nicht moditystr
infoo
trotzdem, auch der Parameter als nicht-const geschrieben.Es gibt 3 Lösungen:
Lösung 1:
Lösung 2:
Lösung 3:
Arrays können auch anstelle von Zeigern verwendet werden, da ein Array bereits ein konstanter Zeiger ist.
quelle
strdup
. Im Gegensatz zu Ihrem Code wird Platz für das abschließende NUL-Zeichen zugewiesen und die Zuordnung nicht überschritten.Tatsächlich ist ein String-Konstanten-Literal 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.
quelle
Vielleicht können Sie dies versuchen:
Für mich geht das
quelle
Ich löse dieses Problem, indem ich dieses Makro irgendwo am Anfang des Codes hinzufüge. Oder füge es hinzu
<iostream>
, hehe.quelle
C_TEXT
ist in Ordnung für einen Funktionsaufruf (foo(C_TEXT("foo"));
), schreit aber nach undefiniertem Verhalten, wenn der Wert in einer Variablen gespeichert ist wiechar *x = C_TEXT("foo");
- jede Verwendung vonx
(abgesehen von der Zuweisung) ist undefiniertes Verhalten, da der Speicher, auf den es zeigt, freigegeben wurde.Ein Grund für dieses Problem (das noch schwerer zu erkennen ist als das Problem, mit
char* str = "some string"
dem andere erklärt haben) ist, dass Sie es verwendenconstexpr
.Es scheint, als würde es sich ähnlich verhalten
const char* str
und daher keine Warnung auslösen, wie es zuvorchar*
aufgetreten ist, sondern es verhält sich stattdessen wiechar* const str
.Einzelheiten
Konstantenzeiger und Zeiger auf eine Konstante. Der Unterschied zwischen
const char* str
undchar* const str
kann wie folgt erklärt werden.const char* str
: Deklarieren Sie str als Zeiger auf ein const char. Dies 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 verwiesen 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. Dies bedeutet, dass der Punkt jetzt konstant ist, die Daten, auf die auch gezeigt wird, jedoch nicht. Der Zeiger kann nicht geändert werden, aber wir können die Daten mit dem Zeiger ä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 verursacht dies keinen Kompilierungsfehler, sondern einen Laufzeitfehler , da die Zeichenfolge höchstwahrscheinlich in einen schreibgeschützten Abschnitt der kompilierten Binärdatei verschoben wird. Diese Aussage wäre sinnvoll, wenn wir dynamisch Speicher zugewiesen hätten, z.char* const str = new char[5];
.const char* const str
: Deklarieren Sie str als const-Zeiger auf ein const-Zeichen. In diesem Fall können wir weder den Zeiger noch die Daten ändern, auf die verwiesen wird.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, mich so
constexpr char* str
zu verhaltenconst char* str
, und nichtchar* const str
, da es visuell näher an dem ersteren zu sein scheint.Außerdem unterscheidet sich die für generierte Warnung
constexpr char* str = "some string"
geringfügig vonchar* str = "some string"
.constexpr char* str = "some string"
:ISO C++11 does not allow conversion from string literal to 'char *const'
char* str = "some string"
:ISO C++11 does not allow conversion from string literal to 'char *'
.Trinkgeld
Sie können C gibberish ish English converter verwenden , um
C
Deklarationen in leicht verständliche englische Anweisungen umzuwandeln und umgekehrt. Dies ist einC
einziges Tool und unterstützt daher keine Dinge (wie constexpr), die exklusiv für sindC++
.quelle
Ich habe auch das gleiche Problem. Und was ich einfach getan habe, ist nur const char * anstelle von char * hinzuzufügen. Und das Problem gelöst. Wie andere oben erwähnt haben, handelt es sich um einen kompatiblen Fehler. C behandelt Strings als char-Arrays, während C ++ sie als const char-Arrays behandelt.
quelle
Für das, was es wert ist, finde ich diese einfache Wrapper-Klasse hilfreich beim Konvertieren von C ++ - Zeichenfolgen in
char *
:quelle
Im Folgenden wird die Lösung veranschaulicht: Weisen Sie Ihre Zeichenfolge einem variablen Zeiger auf ein konstantes Array von Zeichen zu (eine Zeichenfolge ist ein konstanter Zeiger auf ein konstantes Array von Zeichen - plus Längeninformationen):
quelle