Que signifie un pointeur sur pointeur const en C et en C ++?

Je connais la règle de base pour lire les déclarations de droite à gauche et je suis à peu près sûr de savoir ce qui se passait jusqu’à ce qu’un collègue me dise que:

const MyStructure** ppMyStruct; 

signifie “ppMyStruct est un pointeur sur un pointeur const vers une MyStructure (mutable) ” (en C ++).

J’aurais pensé que cela signifiait “ppMyStruct est un pointeur sur un pointeur vers une const MyStructure “. J’ai cherché une réponse dans la spécification C ++, mais apparemment je ne suis pas très bon à ça …

Qu’est-ce que cela signifie en C ++, et est-ce que cela signifie la même chose en C?

Votre collègue a tort. C’est un pointeur (non-const) vers un pointeur (non-const) vers une const MyStructure. En C et C ++.

Dans de tels cas, l’outil cdecl (ou c ++ décl) peut être utile:

  [flolo@titan ~]$ cdecl explain "const struct s** ppMyStruct" declare ppMyStruct as pointer to pointer to const struct s 

Vous avez eu raison dans votre interprétation. Voici une autre façon de le regarder:

 const MyStructure * *ppMyStruct; // ptr --> ptr --> const MyStructure MyStructure *const *ppMyStruct; // ptr --> const ptr --> MyStructure MyStructure * *const ppMyStruct; // const ptr --> ptr --> MyStructure 

Ce sont toutes les alternatives d’un pointeur à un pointeur avec un qualificateur de const. La règle de droite à gauche peut être utilisée pour déchiffrer les déclarations (au moins en C ++; je ne suis pas expert en C).

Vous avez raison

Une autre réponse indiquait déjà la « règle spirale dans le sens des aiguilles d’une montre ». J’ai beaucoup aimé celui-ci – un peu compliqué, cependant.

Votre collègue a tort, et il en va de même pour C et C ++. Essayez ce qui suit:

 typedef struct foo_t { int i; } foo_t; int main() { foo_t f = {123}; const foo_t *p = &f; const foo_t **pp = &p; printf("fi = %d\n", (*pp)->i); (*pp)->i = 888; // error p->i = 999; // error } 

Visual C ++ 2008 donne les erreurs suivantes pour les deux dernières lignes:

 error C2166: l-value specifies const object error C2166: l-value specifies const object 

GCC 4 dit:

 error: assignment of read-only location '**pp' error: assignment of read-only location '*p' 

G ++ 4 dit:

 error: assignment of data-member 'foo_t::i' in read-only structure error: assignment of data-member 'foo_t::i' in read-only structure 

Comme corollaire aux autres commentaires, ne mettez pas «const» en premier. Il appartient vraiment au type. Cela aurait clarifié le sens immédiatement, il suffit de lire RTL comme d’habitude:

 MyStructure const** ppMyStruct; 
 void Foo( int * ptr, int const * ptrToConst, int * const constPtr, int const * const constPtrToConst ) { *ptr = 0; // OK: modifies the pointee ptr = 0; // OK: modifies the pointer *ptrToConst = 0; // Error! Cannot modify the pointee ptrToConst = 0; // OK: modifies the pointer *constPtr = 0; // OK: modifies the pointee constPtr = 0; // Error! Cannot modify the pointer *constPtrToConst = 0; // Error! Cannot modify the pointee constPtrToConst = 0; // Error! Cannot modify the pointer }