Есть ли легкое объяснение того, что означает эта ошибка?
request for member '*******' in something not a structure or union
Я встречался с ним несколько раз за время, когда я изучал C, но у меня нет подсказки относительно того, что это значит.
Есть ли легкое объяснение того, что означает эта ошибка?
request for member '*******' in something not a structure or union
Я встречался с ним несколько раз за время, когда я изучал C, но у меня нет подсказки относительно того, что это значит.
Это также происходит, если вы пытаетесь получить доступ к экземпляру, когда у вас есть указатель, и наоборот:
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
указатель, т.е. включает *
в 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. Указатели важны, не скрывайте звездочки. Пусть они сияют.
Вы пытаетесь получить доступ к члену структуры, но в том, что не является структурой. Например:
struct {
int a;
int b;
} foo;
int fum;
fum.d = 5;
Это может случиться и в следующем случае:
например. если мы рассмотрим функцию 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]));
Это может означать, что вы забыли включить заголовочный файл, который определяет эту структуру/объединение. Например:
Файл 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:
.
.
.
if (getStatus().CHIP_RDY) /* This will generate the error, you must add the #include "foo.h" */
.
.
.
Я перечислял, возможно, все случаи, когда эта ошибка может возникать в коде и его комментариях ниже. Пожалуйста, добавьте к нему, если вы встретите больше случаев.
#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)->
vs *ptr.
и *ptr->
(все случаи, за исключением случая 1)также может отображаться, если:
struct foo { int x, int y, int z }foo;
foo.x=12
вместо
struct foo { int x; int y; int z; }foo;
foo.x=12