Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!uunet!mcsun!unido!mikros!mwtech!martin From: martin@mwtech.UUCP (Martin Weitzel) Newsgroups: comp.lang.c Subject: Re: Circular references in declerations Keywords: circular decleration Message-ID: <677@mwtech.UUCP> Date: 28 Feb 90 11:46:50 GMT References: <973@philtis.cft.philips.nl> Reply-To: martin@mwtech.UUCP (Martin Weitzel) Organization: MIKROS Systemware, Darmstadt/W-Germany Lines: 61 In article <973@philtis.cft.philips.nl> grant@cft.philips.nl (Joe Grant) writes: > > >Calling all C gurus, > > A colleague of mine has run into the following problem. > He needs to use the following declarations: > > typedef union { > int *a; > float *e; > X *x; > } Y > > typedef struct { > int *d; > . > . > . > Y *y; > } X <---- missing here?? I assume the missing X, otherwise your question would not make sense to me. This particluar piece of code should *not* compile (at least not with an ANSI-Compiler), as type X is unknown in the typedef for Y. If you need circular dependencies, you must write this as follows: typedef union uy { ..... ; struct sx *x; ..... } Y; typedef struct sx { ..... ; union uy *y; ..... } X; In the second line, I could have used 'Y' in place of 'union uy' (and hence ommit the union-tag 'uy' in the first typedef), but in the first typedef the use of 'struct sx *' is essential: A C-Compiler will accept this kind of declaration, even if it does not know, what a 'struct sx' will be at this time. Most compilers will *not* accept a type (and hence a pointer to a type) in this situation, if they do not know the type allready. By tradition (%), name spaces for struct- and union-tags (uy, sx) are separated from the name space for typedef-s (X, Y), so you could in fact write. typedef union Y { ..... ; struct X *x; ..... } Y; typedef struct X { ..... ; union Y *y; ..... } X; and of course could change the second line to typedef struct X { ..... ; Y *y; ..... } X; I don't know, if I should recommend to choose the same name as struct/union-tag *and* typedef-d name. If you fully understand the background, it saves remembering 'which is which', but for the 'non-gurus' it might obscure the facts. (%): C++ breaks with this tradition: A struct- or union-tag is *automatically* a type name. -- Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83