Pourquoi est-ce impossible d'avoir:
const int** cpi;
int** pi;
cpi=pi;
mais possible d'avoir:
const int* cpi;
int* pi;
cpi=pi;
Pourquoi est-ce impossible d'avoir:
const int** cpi;
int** pi;
cpi=pi;
mais possible d'avoir:
const int* cpi;
int* pi;
cpi=pi;
La norme permet une petite difference de qualification, mais uniquement au premier niveau d'indirection. Donc int * et const int * peuvent etre utilises de facon equivalentes, mais pas int ** et const int ** (i.e. on ne peut pas briser l'equivalence de qualification de facon recursive).
Il faut donc dire au compilateur que l'on sait ce qu'on fait en forcant le cast:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 cpi = (const int **) pi;
Merci mais j'aimerai COMPRENDRE pourquoi? Ou est le probleme pour le compilateur?
Tu veux comprendre la norme ? Lit le rationale :Envoyé par toto_fr_2002
http://www.lysator.liu.se/c/rat/title.html
Hum... J'ai pas ici les moyens de tester, mais il me semble que ça marche par contre avec un "const int * const *"
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Oui cela marche avec int * const * car en fait on n'a qu'un niveau et celui la marche (voir le premier message).
mais cela n'explique pas le pb ....
J'ai repondu un peu trop vite ....
const int* const * marche aussi ...
mais alors, pourquoi pas
const int**
???????
Non, cela devrait donner un avertissement egalement:Envoyé par toto_fr_2002
donne:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 int main(void) { int **pi1; const int * const *cpi1 = pi1; const int **cp2 = pi1; return 0; }
ce qui est assez normal.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 toto1.c: In function `main': toto1.c:4: warning: initialization from incompatible pointer type toto1.c:5: warning: initialization from incompatible pointer type
Il faut comprendre que les compilateurs acceptent
pour des raisons de commodites, mais que cela viole la regle qui veut que les qualifiers doivent etre conformes des deux cotes d'une expression (ou lors d'un passage d'argument a une fonction). Le comportement anormal est la, pas ailleurs. Mais il a ete adopte pour eviter des casts lourds et inutiles (notamment pour l'appel de fonctions standards demandant des const char *).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 int* pi; const int * cpi = pi;
1. Vu comme ca cela a un sens.
2. Quel compilateur utilise tu. Avec intell 8 sur linux et visual 6 le program
int **pi1;
const int * const *cpi1 = pi1;
marche!
J'utilise gcc 3.2.2. Note qu'il ne donne que des avertissements. La norme indique que jouer avec des equivalences de types qualifies/non qualifies est un comportement indefini, donc chaque compilateur est libre d'avertir ou non l'utilisateur.
De toute facon, il convient d'etre prudent lorsqu'un pointeur nonconst est assigne a un pointeur const. Souvent, cela signifie que le programmeur souhaite modifie la lvalue non-modifiable. Il est ainsi preferable de faire un cast explicite, avec un commentaire qui explique l'intention du codeur (ou, mieux, eviter de faire ce genre de choses).
DAzumba: C'est l'inverse qui se passe, ici: Conversion de nonconst en const (le truc supposé naturel, quoi)
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Partager