It also happens if you're trying to access an instance when you have a pointer, and vice versa:
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 */
As pointed out in a comment, this can be made excruciating if someone goes and typedefs a pointer, i.e. includes the * in a typedef, like so:
typedef struct foo* Foo;
Because then you get code that looks like it's dealing with instances, when in fact it's dealing with pointers:
Foo a_foo = get_a_brand_new_foo();
a_foo->field = FANTASTIC_VALUE;
Note how the above looks as if it should be written a_foo.field, but that would fail since Foo is a pointer to struct. I strongly recommend against typedef:ed pointers in C. Pointers are important, don't hide your asterisks. Let them shine.
It may also happen in the following case:
eg. if we consider the push function of a 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;
}
The error is in the push function and in the commented line. The pointer s has to be included within the parentheses. The correct code:
scanf("%d",&( (*s)->a[++(*s)->head]));