While answer warning: assignment from incompatible pointer type for linklist array, I noticed any undeclared identifier perceded with struct
keyword are considered as forward declared identifiers.
For instance the program below compiles well:
/* Compile with "gcc -std=c99 -W -Wall -O2 -pedantic %" */
#include <stdio.h>
struct foo
{
struct bar *next; /* Linked list */
};
int main(void) {
struct bar *a = 0;
struct baz *b = 0;
struct foo c = {0};
printf("bar -> %p\n", (void *)a);
printf("baz -> %p\n", (void *)b);
printf("foo -> %p, %zu\n", (void *)&c, sizeof c); /* Remove %zu if compiling with -ansi flag */
return 0;
}
My question: Which rule guides a C
compiler to treat undeclared struct identifier
s as forward declared incomplete struct
types?
I think that the most elegant use-case where incomplete struct types are used is something like this :
I.e. double recursion, where a points to b and b points to a. Such cases might be a reason why this feature was included in original C language specification.
Original question is whether all struct identifiers are automatically forward declared. I think that it would be better to say that all incomplete struct definitions are automatically considered as forward declaration.
Edit: Following the comment about documentation, let's look at the C language bible : Kerninghan&Ritchie - The C Programming Language, section "6.5 Self-referential Structures" says :
I agree, that it is possible to implement another way, but I would take this as good motivation from authors of the C language and I agree with them that it is elegant way to implement this.
In addition to the answer provided by 2501, and your comment to it that "In my case, there is not even the forward declaration", the following.
Any use of a
struct tag
counts as a (forward) declaration of the structure type, if it had not been declared before. Although a more formal way would be to say that this simply counts as a type, since the C standard does not mention "forward declarations of structure types", just complete and incomplete structure types (6.2.5p22).6.7.2 Type specifiers tells us that a struct-or-union-specifier is a type-specifier, and 6.7.2.1 Structure and union specifiers paragraph 1 tells us that that in turn struct identifier is a struct-or-union-specifier.
Suppose you have a linked list declaration, something like
then the "implicit forward declaration" of this incomplete type is essential for this structure to work. After all, the type
struct node
is only complete at the terminating semicolon. But you need to refer to it in order to declare thenext
pointer.Also, a
struct node
declaration (of incomplete type) can go out of scope, just like any other declaration. This happens for instance if you have some prototypewhere the
struct unknown
goes out of scope immediately at the end of the declaration. Any further declaredstruct unknown
s are then not the same as this one. That is implied in the text of 6.2.5p22:That is why gcc warns about this:
You can fix this by putting an extra forward declaration before it, which makes the scope start earlier (and therefore end later):
The Standard says (6.2.5.28)
This means the compiler knows how to represent the pointers to any structure, even those that are (yet) undefined.
Your program deals only with pointers to such structures, so it's ok.
It is described in 6.2.5 Types and 6.7.2.3 Tags.
struct identifier
is an object type.