Что означает «запросить членство« ******* »в чем-то, что не является структурой или объединением»? - PullRequest
74 голосов
/ 02 февраля 2010

Есть ли простое объяснение того, что означает эта ошибка?

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

Я сталкивался с этим несколько раз за то время, пока я изучал C, но я понятия не имел, что это значит.

Ответы [ 6 ]

109 голосов
/ 02 февраля 2010

Это также происходит, если вы пытаетесь получить доступ к экземпляру, когда у вас есть указатель, и наоборот:

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 */

Как указано в комментарии, это можно сделать мучительным, если кто-то идет и typedef s указатель, то есть включает * в typedef, например, так:

typedef struct foo* Foo;

Потому что тогда вы получаете код, который выглядит как будто он имеет дело с экземплярами, тогда как на самом деле он имеет дело с указателями:

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

Обратите внимание, что вышеприведенное выглядит так, как будто оно должно быть записано a_foo.field, но это не удастся, поскольку Foo является указателем на struct. Я настоятельно рекомендую против typedef: указатели ed в C. Указатели важны, не скрывайте звездочки. Пусть они сияют.

17 голосов
/ 02 февраля 2010

Вы пытаетесь получить доступ к члену структуры, но к чему-то, что не является структурой. Например:

struct {
    int a;
    int b;
} foo;
int fum;
fum.d = 5;
5 голосов
/ 13 апреля 2013

Это также может произойти в следующем случае:

например.если мы рассмотрим функцию push стека:

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

Ошибка в функции push и в закомментированной строке.Указатель s должен быть включен в скобки.Правильный код:

scanf("%d",&( (*s)->a[++(*s)->head]));
2 голосов
/ 08 марта 2017

Я перечислил, возможно, все случаи, когда эта ошибка может возникать в коде и его комментариях ниже. Пожалуйста, добавьте к нему, если вы столкнетесь с большим количеством дел.

#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
}

Основные идеи просты:

  • Используйте . со структурной переменной. (Случаи 2 и 4)
  • Используйте -> с указателем на структуру. (Случаи 1 и 3)
  • Если вы достигнете структурной переменной или указателя на структурную переменную с помощью следующего указателя, заключите указатель в квадратную скобку: (*ptr). и (*ptr)-> против *ptr. и *ptr-> (все случаи, кроме случая 1)
  • Если вы используете следующие указатели, убедитесь, что вы правильно достигли указателя на структуру или структуру в зависимости от того, что вам нужно. (Случай 5, особенно 5,5)
1 голос
/ 30 мая 2016

Это может означать, что вы забыли включить заголовочный файл, который определяет эту структуру / объединение. Например:

файл 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();

main.c file:

.
.
.
if (getStatus().CHIP_RDY) /* This will generate the error, you must add the  #include "foo.h" */
.
.
.
0 голосов
/ 09 марта 2012

также может появиться, если:

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

foo.x=12

вместо

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

foo.x=12
...