et vous ne serez pas le même avertissement. Sinon, vous pouvez jeter v
lorsque vous appelez f
Vous pouvez utiliser un pointer-to-T
(pour tout type T
) où un pointer-to-const-T
devrait. Cependant, la règle (une exception explicite) qui autorise de légères discordances dans les types de pointeurs qualifiés n'est pas appliquée de manière récursive, mais uniquement au niveau supérieur. (const char **
est pointer-to-pointer-to-const-char
, et l'exception ne s'applique pas.)
La raison pour laquelle vous ne pouvez pas attribuer une valeur char **
à un pointeur const char **
est quelque peu obscur. Étant donné que le qualificatif const
existe, le compilateur souhaite vous aider à tenir vos promesses de ne pas modifier les valeurs const
. C'est pourquoi vous pouvez attribuer un char *
à un const char *
, mais pas l'inverse: il est clairement sûr de ajouterconst
-ness à un pointeur simple, mais il serait dangereux de l'enlever. Cependant, supposons que vous avez effectué la série de missions plus complexes suivantes:
const char c = 'x'; /* 1 */
char *p1; /* 2 */
const char **p2 = &p1; /* 3 */
*p2 = &c; /* 4 */
*p1 = 'X'; /* 5 */
Dans la ligne 3, nous attribuons un char **
à un const char **
. (Le compilateur devrait se plaindre.) Dans la ligne 4, nous affectons const char *
à const char *
; C'est clairement légal. À la ligne 5, nous modifions ce que char *
fait valoir - ceci est censé être légal. Cependant, p1 finit par pointer vers c, qui est const
. Cela est arrivé à la ligne 4, parce que * p2 était vraiment p1. Cela a été mis en place à la ligne 3, qui est une affectation d'un formulaire qui n'est pas autorisé, et c'est exactement la raison pour laquelle la ligne 3 est refusée.
L'attribution d'un char **
à un const char **
(comme dans la ligne 3, et dans la question d'origine) n'est pas immédiatement dangereux. Mais il met en place une situation dans laquelle la promesse de p2 - que la valeur finalement pointée ne sera pas modifiée - ne peut pas être conservée.
(C++ a des règles plus complexes pour attribuer const
pointeurs aux qualifiés qui vous permettent de faire plusieurs types de missions sans encourir des avertissements, mais toujours protéger contre toute tentative accidentelle de modifier les valeurs const
. C++ ne permettent toujours pas l'attribution d'un char **
à un const char **
, mais il vous permettra de sortir avec l'attribution d'un char **
à un const char * const
*.)
En C, si vous devez céder ou passer des pointeurs qui ont discordances qualification à autre que le premier niveau d'indirection, vous devez utiliser des moulages explicites (par exemple (const char **
) dans ce cas), bien que, comme toujours, la nécessité d'un tel plâtre peut indiquer une profondeur problème que la distribution ne corrige pas vraiment.
Références: ISO Sec. 6.1.2.6, Sec. 6.3.16.1, Sec. 6.5.3 H & S Sec. . 7.9.1 pp 221-2
Sur quelle ligne obtenez-vous l'avertissement? – LeopardSkinPillBoxHat