Initialisierung zwischen den Typen „const int ** const“ und „int **“ ist nicht erlaubt, warum?

StackOverflow https://stackoverflow.com/questions/1468148

Frage

Mit V1.8 z / OS XL-C-Compiler, mit Warnungen aufgebockten mit INFO (ALL), erhalte ich die folgende Warnung in Zeile 4 des Codes unter:

WARNING CCN3196 Initialization between types "const int** const" and "int**" 
                is not allowed.


1  int foo = 0;
2  int *ptr = &foo;

3  const int * const fixed_readonly_ptr = ptr;

4  const int ** const fixed_ptr_to_readonly_ptr = &ptr;

Ich kann nicht wickeln meinen Kopf herum, warum ich diese Warnung bin immer. Wenn ich einen int Zeiger auf einen const Zeiger auf const int (Linie 3) zuordnen kann, warum dann nicht zuweisen ich die Adresse eines int Zeiger auf einen const Zeiger auf const int auf Zeiger? Was bin ich?

Beachten Sie den obigen Code ist ein abgespeckte Beispiel zeigt nur das Problem, das ich bin in einer kleinen Menge an Code zu stoßen. Der wahre Zusammenhang ist, dass ich ein const Zeiger müssen Zeiger (struct s ** const) auf struct und es als Argument für eine Funktion am Übergang, der Parameter ist als const Zeiger definiert Zeiger struct (const struct s const ** const). Dies liegt daran, dass die Funktion nicht die Daten in der struct ändern (folglich die erste const) und es nicht den Zeiger Parameter ändern, die immer die in (und somit die zweite const) weitergegeben Adresse hält. Der Wert des Zeigers wies auf kann durch die Art und Weise verändert werden (das ist, warum es keine drittes const zwischen dem **).

War es hilfreich?

Lösung

Die C-Regel ist, dass Sie einen Zeiger auf etwas auf einen Zeiger umwandeln können, etwas const, aber dass etwas genau die gleiche Art einschließlich const und volatilen Qualifikationen weiter unten in der Kette sein muss.

Die Begründung für diese Regel ist, dass, wenn der zweite dieser beiden Linien wurde erlaubt:

int *ptr;

const int ** const fixed_ptr_to_readonly_ptr = &ptr;

dann kann dies verwendet werden, um Typ-Sicherheit ohne Guss zu brechen.

const int i = 4;

// OK, both sides have type const int *
*fixed_ptr_to_readonly_ptr = &i;

// the value of fixed_ptr_to_readonly_ptr is still &ptr
// the value of ptr is now &i;

*ptr = 5;

// oops, attempt to change the value of i which is const

Andere Tipps

Es ist eine Art Sicherheitsverletzung. Betrachten Sie diesen Code (I gemischt const ein wenig herum, um klarzustellen, ob es gilt für Zeiger oder pointee, aber semantisch bedeutet es genau die gleiche Sache):

int* p = 0;
int const** pp = &p; // presumably ok

int const c = 123;
*pp = &c; // okay, &c is int const*, and *p is int const* lvalue

*p = 666; // okay, *p is int lvalue

// wait, so we just changed the value of (const) c above, with no const_cast!

Dies ist eine Art-Sicherheitsverletzung. Sie wollen wahrscheinlich ein const int * const verwenden * statt. Siehe http://www.parashift.com/c++ -FAQ-lite / konst-correctness.html # faq-18.17

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top