Чи є просте пояснення того, що означає ця помилка?
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
вказує покажчик, тобто включає *
in в 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]));
Я перелічив, можливо, усі випадки, коли ця помилка може трапитися в коді та коментарі нижче. Будь ласка, додайте до нього, якщо натрапите на більше справ.
#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)Це може означати, що ви забули включити файл заголовка, який визначає цю структуру / об'єднання. Наприклад:
файл 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" */
.
.
.
Я це побачив, коли намагався отримати доступ до учасників.
Моя структура була такою:
struct test {
int a;
int b;
};
struct test testvar;
Зазвичай ми отримуємо доступ до членів структури як
testvar.a;
testvar.b;
Я прийняв тествара за вказівника і зробив це.
testvar->a;
Саме тоді я побачив цю помилку.
запит члена "а" у чомусь, що не є структурою чи об'єднанням