Que signifie «demande de membre ‘*******’ dans quelque chose qui n’est pas une structure ou un syndicat»?

Existe-t-il une explication facile de ce que signifie cette erreur?

request for member '*******' in something not a structure or union 

Je l’ai rencontré plusieurs fois au cours de mon apprentissage du C, mais je n’ai aucune idée de ce que cela signifie.

Cela se produit également si vous essayez d’accéder à une instance lorsque vous avez un pointeur, et inversement:

 struct foo { int x, y, z; }; struct foo a, *b = &a; bx = 12; /* This will generate the error, should be b->x or (*b).x */ 

Comme indiqué dans un commentaire, cela peut être insoutenable si quelqu’un va et typedef sa pointeur, c’est-à-dire qu’il inclut le * dans un typedef, comme ceci:

 typedef struct foo* Foo; 

Car alors vous obtenez du code qui ressemble à des instances, alors qu’il s’agit en fait de pointeurs:

 Foo a_foo = get_a_brand_new_foo(); a_foo->field = FANTASTIC_VALUE; 

Notez que ce qui précède semble devoir être écrit a_foo.field , mais cela échouerait car Foo est un pointeur sur struct. Je recommande fortement de ne pas utiliser les pointeurs typedef dans C. Les pointeurs sont importants, ne cachez pas vos astérisques. Laissez-les briller.

Vous essayez d’accéder à un membre d’une structure, mais dans quelque chose qui n’est pas une structure. Par exemple:

 struct { int a; int b; } foo; int fum; fum.d = 5; 

Cela peut également arriver dans le cas suivant:

par exemple. si l’on considère la fonction push d’une stack:

 typedef struct stack { int a[20]; int head; }stack; void push(stack **s) { int data; printf("Enter data:"); scanf("%d",&(*s->a[++*s->head])); /* this is where the error is*/ } main() { stack *s; s=(stack *)calloc(1,sizeof(stack)); s->head=-1; push(&s); return 0; } 

L’erreur est dans la fonction push et dans la ligne commentée. Le pointeur s doit être inclus dans les parenthèses. Le code correct:

 scanf("%d",&( (*s)->a[++(*s)->head])); 

Cela signifie peut-être que vous avez oublié d’inclure un fichier d’en-tête qui définit cette structure / union. Par exemple:

fichier foo.h:

 typedef union { struct { uint8_t FIFO_BYTES_AVAILABLE : 4; uint8_t STATE : 3; uint8_t CHIP_RDY : 1; }; uint8_t status; } RF_CHIP_STATUS_t; RF_CHIP_STATUS_t getStatus(); 

fichier principal.c:

 . . . if (getStatus().CHIP_RDY) /* This will generate the error, you must add the #include "foo.h" */ . . . 

J’ai énuméré éventuellement tous les cas où cette erreur peut se produire dans le code et ses commentaires ci-dessous. S’il vous plaît append à cela, si vous rencontrez plus de cas.

 #include #include typedef struct AStruct TypedefedStruct; struct AStruct { int member; }; void main() { /* Case 1 ============================================================================ Use (->) operator to access structure member with structure pointer, instead of dot (.) operator. */ struct AStruct *aStructObjPtr = (struct AStruct *)malloc(sizeof(struct AStruct)); //aStructObjPtr.member = 1; //Error: request for member 'member' in something not //a structure or union. //It should be as below. aStructObjPtr->member = 1; printf("%d",aStructObjPtr->member); //1 /* Case 2 ============================================================================ We can use dot (.) operator with struct variable to access its members, but not with with struct pointer. But we have to ensure we dont forget to wrap pointer variable inside brackets. */ //*aStructObjPtr.member = 2; //Error, should be as below. (*aStructObjPtr).member = 2; printf("%d",(*aStructObjPtr).member); //2 /* Case 3 ============================================================================= Use (->) operator to access structure member with typedefed structure pointer, instead of dot (.) operator. */ TypedefedStruct *typedefStructObjPtr = (TypedefedStruct *)malloc(sizeof(TypedefedStruct)); //typedefStructObjPtr.member=3; //Error, should be as below. typedefStructObjPtr->member=3; printf("%d",typedefStructObjPtr->member); //3 /* Case 4 ============================================================================ We can use dot (.) operator with struct variable to access its members, but not with with struct pointer. But we have to ensure we dont forget to wrap pointer variable inside brackets. */ //*typedefStructObjPtr.member = 4; //Error, should be as below. (*typedefStructObjPtr).member=4; printf("%d",(*typedefStructObjPtr).member); //4 /* Case 5 ============================================================================ We have to be extra carefull when dealing with pointer to pointers to ensure that we follow all above rules. We need to be double carefull while putting brackets around pointers. */ //5.1. Access via struct_ptrptr and -> struct AStruct **aStructObjPtrPtr = &aStructObjPtr; //*aStructObjPtrPtr->member = 5; //Error, should be as below. (*aStructObjPtrPtr)->member = 5; printf("%d",(*aStructObjPtrPtr)->member); //5 //5.2. Access via struct_ptrptr and . //**aStructObjPtrPtr.member = 6; //Error, should be as below. (**aStructObjPtrPtr).member = 6; printf("%d",(**aStructObjPtrPtr).member); //6 //5.3. Access via typedefed_strct_ptrptr and -> TypedefedStruct **typedefStructObjPtrPtr = &typedefStructObjPtr; //*typedefStructObjPtrPtr->member = 7; //Error, should be as below. (*typedefStructObjPtrPtr)->member = 7; printf("%d",(*typedefStructObjPtrPtr)->member); //7 //5.4. Access via typedefed_strct_ptrptr and . //**typedefStructObjPtrPtr->member = 8; //Error, should be as below. (**typedefStructObjPtrPtr).member = 8; printf("%d",(**typedefStructObjPtrPtr).member); //8 //5.5. All cases 5.1 to 5.4 will fail if you include incorrect number of * // Below are examples of such usage of incorrect number *, correspnding // to int values assigned to them //(aStructObjPtrPtr)->member = 5; //Error //(*aStructObjPtrPtr).member = 6; //Error //(typedefStructObjPtrPtr)->member = 7; //Error //(*typedefStructObjPtrPtr).member = 8; //Error } 

Les idées sous-jacentes sont droites:

  • Utiliser avec variable de structure. (Cas 2 et 4)
  • Utilisez -> avec le pointeur sur la structure. (Cas 1 et 3)
  • Si vous atteignez une variable de structure ou un pointeur pour structurer une variable en suivant le pointeur, enroulez le pointeur à l’intérieur du crochet: (*ptr). et (*ptr)-> vs *ptr. et *ptr-> (Tous les cas sauf le cas 1)
  • Si vous atteignez en suivant les pointeurs, assurez-vous d’avoir correctement atteint le pointeur sur struct ou struct, selon ce qui est souhaité. (Cas 5, surtout 5.5)

peut également apparaître si:

 struct foo { int x, int y, int z }foo; foo.x=12 

au lieu de

 struct foo { int x; int y; int z; }foo; foo.x=12