ron@motmpl.UUCP (Ron Widell) (07/12/89)
My apologies if the previous posting went out, I tried to cancel it. In trying to understand how to define, declare and use structures, unions and pointers to same, I hacked up the following piece of strange code. Now, I know it's ugly, but I thought that it was legal, yet I can't get any (SGS, Sun, TurboC, MSC) compiler to take it unless I define BURP before trying to compile. As I interpret K&R, 1e (page 120 in particular); I think it should be legal, so why won't any of the compilers I've tried accept it? Could I be wrong and the whole world be right :-)? #include <stdio.h> main() { union { unsigned short foo; #ifdef BURP struct burp { #else struct { #endif unsigned char fuz; unsigned char bar; } baz, *sptr; } glorp, *uptr; #ifdef BURP struct burp baz, *sptr; #endif uptr = &glorp; sptr = &glorp.baz; uptr->foo = (unsigned short)0x4142; (void)putchar((char)sptr->fuz); (void)putchar('\n'); (void)putchar((char)sptr->bar); (void)putchar('\n'); return 0; } Here's the output from lint: junk.c ============== (22) sptr undefined warning: illegal combination of pointer and integer: (22) operator = warning: struct/union or struct/union pointer required (24) (26) and here's the output (stderr) from SGS cc: "junk.c", line 22: sptr undefined "junk.c", line 22: warning: illegal pointer/integer combination, op = "junk.c", line 24: warning: struct/union or struct/union pointer required "junk.c", line 24: warning: struct/union or struct/union pointer required "junk.c", line 26: warning: struct/union or struct/union pointer required "junk.c", line 26: warning: struct/union or struct/union pointer required Well, at least they agree :-). BTW #1- I know that the *code* is bogus and very nonportable, and probably works only by accident. It's there *only* to give lint and cc something to munch on. I'm only interested in the legality of the union{..struct{..};}; definition/declaration. BTW #2- What I *think* I'm defining is a union with three members: 1) an unsigned short (on the target machine it's an int). 2) a structure of 2 unsigned chars. 3) a pointer to a structure of 2 unsigned chars. Please respond via e-mail, I will summarize. Flame as required. Regards, -- Ron Widell, Field Applications Eng. |UUCP: {...}mcdchg!motmpl!ron Motorola Semiconductor Products, Inc., |Voice:(612)941-6800 9600 W. 76th St., Suite G | I'm from Silicon Tundra, Eden Prairie, Mn. 55344 -3718 | what could I know?
chris@mimsy.UUCP (Chris Torek) (07/18/89)
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