While they are incomplete types, they are not completely
unknown types. For example, forward-declaring a struct
tells the compiler that the type is a struct, which in
turn tells the compiler how to represent its pointers
(since the C standard guaranteeds struct pointers to
share the same representation, not true of all types
And of course, if you forward-declare a function, that
completely defines the interface to said function. But
I don't think we're talking about function declarations.
If you could arbitrarily specify types, like:
without ever telling the compiler what 'number' means
(is it a float? an integer? a complex-value struct?),
it would make forward-declarations superfluous.