Initialisation entre les types « const int ** const » et « int ** » n'est pas autorisé, pourquoi?

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

Question

Utilisation de compilateur V1.8 z / OS XL C, avec des avertissements Jacked-up en utilisant INFO (ALL), je reçois l'avertissement suivant la ligne 4 du code ci-dessous:

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;

Je ne peux pas envelopper ma tête pourquoi je reçois cet avertissement. Si je peux assigner un pointeur int à un pointeur const const int (ligne 3), alors pourquoi ne puis-je attribuer l'adresse d'un pointeur int à un pointeur const pointeur sur const int? Qu'est-ce que je manque?

Notez que le code ci-dessus est un exemple amincie montre juste la question que je rencontre dans une petite quantité de code. Le contexte réel est que j'ai un pointeur const pointeur sur struct (s struct ** const) et je passe comme argument à une fonction qui est définie comme paramètre est un pointeur const pointeur sur const struct (const struct s ** const). En effet, la fonction ne modifiera pas les données dans le struct (d'où le premier const) et il ne modifie pas le paramètre de pointeur qui contient toujours l'adresse passée dans (d'où le deuxième const). La valeur du pointeur pointé peut être modifié par la façon (ce qui est la raison pour laquelle il n'y a pas un troisième const entre le **).

Était-ce utile?

La solution

La règle C est que vous pouvez convertir un pointeur vers quelque chose à un pointeur vers const quelque chose, mais que quelque chose doit être exactement le même type y compris const et les qualifications volatiles en aval de la chaîne.

La justification de cette règle est que si la seconde de ces deux lignes ont été autorisés:

int *ptr;

const int ** const fixed_ptr_to_readonly_ptr = &ptr;

cela peut être utilisé pour briser la sécurité de type sans plâtre.

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

Autres conseils

Il est une violation de la sécurité de type. Considérez ce code (je Shuffled const un peu pour préciser si elle applique le pointeur ou pointée, mais sémantiquement cela signifie exactement la même chose):

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!

Ceci est une violation de type sécurité. Vous voulez probablement utiliser un const int * const * au lieu. Voir http://www.parashift.com/c++ -FAQ-lite / const-correctness.html # faq-18,17

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top