Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!iuvax!uxc.cso.uiuc.edu!tank!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.c Subject: Re: struct/union/pointer query (Why isn't this legal?) Message-ID: <18602@mimsy.UUCP> Date: 18 Jul 89 04:53:12 GMT References: <1298@motmpl.UUCP> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 88 In article <1298@motmpl.UUCP> ron@motmpl.UUCP (Ron Widell) writes: >Please respond via e-mail, I will summarize. Good suggestion, but I will ignore it. Anyway: >... As I interpret K&R, 1e (page 120 in particular); I think [the >following code, with #ifdef's edited away] should be legal, so why >won't any of the compilers I've tried accept it? >int main() { > union { > unsigned short foo; > struct { > unsigned char fuz; > unsigned char bar; > } baz, *sptr; > } glorp, *uptr; > > uptr = &glorp; > sptr = &glorp.baz; > uptr->foo = (unsigned short)0x4142; The best way to understand what has been declared above is to `unwind' it. This requires adding tags to any structure or union declarations that do not already have them. Here, the inner `struct' (containing `fuz' and `bar') has no tag, so add one. At the same time, move the declaration out: struct ss { unsigned char fuz; unsigned char bar; }; Likewise, the union has no tag, so add one: union uu { unsigned short foo; struct ss baz, *sptr; }; Next, go through all the struct and union declarations and expand type names for all members. Here only the union has any commas: union uu { unsigned short foo; struct ss baz; struct ss *sptr; }; Now that all structures and unions are fully named, add the main() function and its local variables. What we now have is this: struct ss { unsigned char fuz; unsigned char bar; }; union uu { unsigned short foo; struct ss baz; struct ss *sptr; }; main() { union uu glorp, *uptr; uptr = &glorp; --> sptr = &glorp.baz; uptr->foo = (unsigned short)0x4142; [the rest is missing, unnecessary] The line marked with the arrow (-->) is where things go wrong. It should be obvious at this point that main() has only two local variables, one (`glorp') of type `union uu' and one (`uptr') of type `pointer to union uu'. The local variable `sptr' simply does not exist. (glorp contains a field called sptr, however.) >... I'm only interested in the legality of the union{..struct{..};}; >definition/declaration. What I *think* I'm defining is a union with >three members: 1) an unsigned short ... . 2) a structure of 2 unsigned >chars. 3) a pointer to a structure of 2 unsigned chars. That is indeed what you defined. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris