web-dev-qa-db-fra.com

Que signifie "demande de membre '*******' dans quelque chose qui ne soit pas une structure ou un syndicat"?

Existe-t-il une explication simple de la signification de cette erreur?

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

Je l'ai rencontré plusieurs fois depuis que j'apprenais le C, mais je n'ai aucune idée de ce que cela signifie.

74
Pieter

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

struct foo
{
  int x, y, z;
};

struct foo a, *b = &a;

b.x = 12;  /* This will generate the error, should be b->x or (*b).x */

Comme indiqué dans un commentaire, ceci peut être rendu atroce si quelqu'un va et typedefs un pointeur, c'est-à-dire inclut le * dans un typedef, comme ceci:

typedef struct foo* Foo;

Parce qu'alors, vous obtenez un code qui ressemble à des instances, alors qu'en fait il concerne des pointeurs:

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

Notez comment ce qui précède semble être écrit a_foo.field, mais cela échouerait puisque Foo est un pointeur sur struct. Je recommande fortement contretypedef: des pointeurs en C. Les pointeurs sont importants, ne cachez pas vos astérisques. Laissez-les briller.

109
unwind

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;
17

Cela peut aussi arriver dans le cas suivant:

par exemple. si on considère la fonction Push d'une pile:

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 entre parenthèses. Le code correct:

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

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 ajouter à cela, si vous rencontrez plus de cas.

#include<stdio.h>
#include<malloc.h>

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:

  • Utilisation . avec variable de structure. (Cas 2 et 4)
  • Utilisation -> avec un pointeur sur la structure. (Cas 1 et 3)
  • Si vous atteignez la variable de structure ou le pointeur sur la variable de structure en suivant le pointeur, enroulez le pointeur à l'intérieur du crochet: (*ptr). et (*ptr)-> contre *ptr. et *ptr-> _ (Tous les cas sauf le cas 1)
  • Si vous atteignez en suivant les pointeurs, assurez-vous que vous avez correctement atteint le pointeur vers struct ou struct, selon ce que vous souhaitez. (Cas 5, en particulier 5.5)
2
Mahesha999

Cela peut signifier 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 main.c:

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

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
0
Nahum