forward references in typedefs

david.f.prosser dfp at cbnewsl.ATT.COM
Sat Jul 22 00:56:14 AEST 1989


In article <55480 at tut.cis.ohio-state.edu> George M. Jones <george at cis.ohio-state.edu> writes:
>I have noticed what I consider anomolous behavior when using forward references
>in structs & typedefs and would would like to know whether things behave as
>they do because (a) that's just the way the compilers choose to implement
>a fuzzy point or (b) there is some definition (ansi, K&R) that say this is
>[in]correct behavior.
>
>
>The following code compiles (Sun, GCC, Green Hills) just fine as expected:
>
>  struct one
>    {
>      struct two_t *foo;
>    } one_t;
>  
>  struct two
>    {
>      struct one_t *bar;
>    } two_t;
>

There is either a pair of typos or a misunderstanding in the above.
Structure tags are in a different namespace from regular identifiers.
The structures "struct one_t" and "struct two_t" have never been
defined.  Moreover, since a "_t" ending is usually used for typedef
names, my guess is that typedefs were intended for these, instead of
regular objects.

	typedef struct one { struct two *foo; } one_t;
	typedef struct two { struct one *bar; } two_t;

>
>However all the compilers I tried appear to be choaking on the forward 
>reference to two_t in the following chunk of code
>
>  typedef struct one
>    {
>      two_t *foo;
>    } one_t;
>  
>  typedef struct two
>    {
>      one_t *bar;
>    } two_t;
>  4:35pm> cc -c bad.c
>  "bad.c", line 3: syntax error at or near variable name "two_t"
>  "bad.c", line 4: zero sized structure
>
>Any definitive answers from the knowledgable clientel of this newsgroup ?

Since "two_t" in the above is completely unknown, the compiler has no
idea what is intended.  At least the "shape" of the type being described
by the typedef name must be declared prior to use of a typedef name.
If I were writing this sort of code, I'd probably use typedef names for
what ANSI C calls "incomplete types":

	typedef struct one one_t;
	typedef struct two two_t;

At this point, sizeof(one_t) and sizeof(two_t) are not known, but
sizeof(one_t *) and sizeof(two_t *) are known.  Note that this implies
that all structure (and union) pointers must be the same size.  As this
pointer, the following declarations are valid:

	struct one { two_t *foo; };
	struct two { one_t *bar; };

The main advantage gained by separating the typedef declaration from the
structure is that a single common header file can contain the typedefs
while headers for particular modules can contain the complete structure.
Only those parts of the program that need to know the members of the
structure must include the detailed header.

Dave Prosser	dfp at attunix.att.com



More information about the Comp.lang.c mailing list