Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.milw.wisc.edu!cs.utexas.edu!tut.cis.ohio-state.edu!rutgers!dptg!att!cbnewsl!dfp From: dfp@cbnewsl.ATT.COM (david.f.prosser) Newsgroups: comp.lang.c Subject: Re: forward references in typedefs Message-ID: <1196@cbnewsl.ATT.COM> Date: 21 Jul 89 14:56:14 GMT References: <55480@tut.cis.ohio-state.edu> Reply-To: dfp@cbnewsl.ATT.COM (david.f.prosser) Organization: AT&T Bell Laboratories Lines: 74 In article <55480@tut.cis.ohio-state.edu> George M. Jones 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@attunix.att.com