const char ** in void * umwandeln? [Duplikat]

9

Betrachten Sie diesen Code:

%Vor%

Kompiliert fein mit gcc 4.9.2 -pedantic aber cl 18 (das von VS2013) mit Standardoptionen sagt warning C4090: 'function' : different 'const' qualifiers in der memset-Zeile.

Jetzt ist caps ein Zeiger auf einen Zeiger auf const char? Also der Zeiger selbst ist nicht const, daher sollte er in void* ohne Probleme umgewandelt werden, denke ich, aber cl scheint automatisch const void* daraus zu machen, was die Warnung erzeugt. Ist das eine korrekte Erklärung für das, was vor sich geht? Und das ist nicht standardmäßiges Verhalten, oder?

    
stijn 16.03.2015, 11:05
quelle

3 Antworten

3

Der Compiler ist übereifrig (lesen als: Compiler Bug).

const char** caps bedeutet, dass caps ein Zeiger (der nicht konstant ist) auf einen anderen Zeiger (der auch nicht konstant ist) zu einem char , der konstant ist. Das heißt, Sie versprechen, diese char nicht durch Umleitungen zu ändern, die caps überschreiten.
Das bedeutet, dass Sie mit dem Compiler formell den folgenden Vertrag abschließen:

  1. Sie dürfen caps ändern.
  2. Sie dürfen *caps (das char* , auf das caps verweist) ändern.
  3. Sie sind nicht berechtigt, **caps zu ändern (das char , das *caps zeigt auf (welches caps auf Punkte zeigt)) über diese Kettenzeiger .
  4. Es wird nichts über irgendjemand anderen gesagt (z. B. Alias-Zeiger), der den Wert dieses Zeichens ändert.

    const char ** Groß- / Kleinschreibung = malloc (sizeof (char *));

initialisiert caps mit einem Wert, der legal ist. Für den Fall, dass malloc fehlschlägt, ist dieser Wert ein Null-Zeiger, aber auch dies ist aus Sicht der Sprache im Allgemeinen vollkommen legal (obwohl dies zum Absturz des folgenden memset führen würde). In C ++ müssten Sie das void* , das von malloc zurückgegeben wird, explizit umwandeln, aber C erlaubt das ganz gut.

%Vor%

lässt meine Haare aufstehen (ich bin ein C ++ - Programmierer), aber aus der Sicht der C-Sprache ist es trotzdem eine vollkommen legale Angelegenheit.
Was es tut ist überschreiben die bisher zugewiesenen, aber nicht initialisiert (und von caps gezeigt) Speicherblock, der den zweiten Zeiger mit einer Anzahl von Null Bytes gleich der Größe eines Zeigers enthält (a char Zeiger, als es passiert).

Die Bibliotheksfunktion memset , die eine nicht-konstante void* übernimmt, füllt einfach die Anzahl der Bytes, die Sie fragen (hier sizeof(char*) ) mit dem von Ihnen angegebenen Wert (hier: Null). Sie müssen sich nicht um den Vertrag kümmern, den Sie mit dem Compiler abgeschlossen haben. Aber trotzdem verletzt es keine Regeln. Es überschreibt den Zeiger, nicht den angezeigten konstanten Wert.
Ja, es schreibt ein paar char -Werte in etwas, das nicht ist ein Array von char s (weshalb meine Haare aufstehen), aber gut ... das ist ... legal Es ist genau das, was memset schließlich tun soll, und es wird höchstwahrscheinlich "wie erwartet funktionieren". Es wird den Zeiger auf ein Null-Bit-Muster setzen, das - abgesehen von einigen sehr seltenen exotischen Architekturen - einem Nullzeiger entspricht.

Zu keinem Zeitpunkt wurde der Speicherort **caps geändert (oder auch nur darauf zugegriffen), also ist das alles vollkommen legal, Sie haben nichts von Ihren Versprechen gebrochen.

Die Warnung ist daher falsch.

    
Damon 16.03.2015, 12:39
quelle
-3

Sie können keinen Zeiger auf eine Konstante ( const X * ) auf eine void * umwandeln: das würde sein const -Qualifikationsmerkmal verwerfen.

memset muss diese Daten ändern, deshalb benötigt es einen void * -Parameter und nicht einen const void * -Parameter.

    
nyarlathotep108 16.03.2015 11:10
quelle
-3

Wie Sie es geschrieben haben, bezieht sich const auf das Zeichen, nicht auf den Zeiger. Offensichtlich macht es wenig Sinn, Speicher nur zu reservieren, um zu deklarieren, dass er niemals modifiziert wird (was bedeutet, dass er niemals initialisiert wird).

Wenn der Zeiger selbst const sein soll, sollten Sie schreiben:

%Vor%

Sie können den zweiten Zeiger auch const machen, aber das macht keinen Sinn, als das char const.

zu machen     
Kevin Keane 16.03.2015 11:12
quelle

Tags und Links