In struct a
you refer to a pointer to struct abc
, so the compiler has no need for more information about it to compute the size of the d
member.
In a later stage, it will check that struct abc
is defined, if needed (for exemple if it is dereferenced). This explains the rationale for the standard which
forbids to declare variables of unknown type (abc
, when not forwarded, is such an unknown type)
allows to declare them as pointers to incomplete type. (struct abc
is an incomplete type: at least it is known to be some struct
).
Practically, declaring a structure as
struct a {
struct abc *d;
}
amounts to forwarding the declaration of (struct) type abc
, as in
struct abc; // forward
struct a {
abc *d; // legal
};
However the type abc
is incomplete, so the following is illegal
struct z {
struct abc y; // error : incomplete struct type
}
For the curiosity, this is OK:
struct A {
struct B* ptr1; // forwards declaration of B, and use it
B* ptr2; // B is a known (incomplete-)type name now
}