[comp.lang.c] I'd like to . . .

deem@interlan.UUCP (Mike Deem) (11/11/87)

Here is another "I'd like to be able to do this in C" suggestion.

There are times I would like to be able to say:

  s.a = 4321;
    .
    .
    .
  s.b = 123.4;

where a and b occupy the same memory but s is a structure and has other feilds,
say c and d, that could be accessed by:

  s.c

and

  s.d

I think this could be declared something like:

   struct {
     int      c;              /* c takes up space                       */
     union {                  /* no identifier                          */
       int    a;              /* both a and b are in the same space and */
       float  b;              /* that space follows c's                 */
     };                       /* no identified here either              */
     char     d;              /* d takes space following the a b space  */
   } s;

I know I could give the union a name, say u, and write:

  s.u.a

but when s u and a are replaced with "meaningful" identifiers or many 
structures are nested, things get to long.

rst@think.COM (Robert Thau) (11/12/87)

In article <511@interlan.UUCP> deem@interlan.UUCP (Mike Deem) writes:
>I think this could be declared something like:
>
>   struct {
>     int      c;              /* c takes up space                       */
>     union {                  /* no identifier                          */
>       int    a;              /* both a and b are in the same space and */
>       float  b;              /* that space follows c's                 */
>     };                       /* no identified here either              */
>     char     d;              /* d takes space following the a b space  */
>   } s;

"Fixed in C++", which supports exactly this syntax.  

In plain C, there is no way to suppress the name of the union
entirely, so the typical thing is to hide it with a little
preprocessor skullduggery.  For example,

struct s {
  int      c;              /* c takes up space                       */
  union {
    int    A;              /* both a and b are in the same space and */
    float  B;              /* that space follows c's                 */
  } u;
  char     d;              /* d takes space following the a b space  */
};

#define a u.A
#define b u.B

main()
{
	struct s s;
	printf("&s.a = %d, &s.b = %d, &s.c = %d, &s.d=%d\n",
	       (int)&s.a, (int)&s.b, (int)&s.c, (int)&s.d);
}

on a Sun-3 (where pointers fit in ints) produces the output:

&s.a = 251657764, &s.b = 251657764, &s.c = 251657760, &s.d=251657768

which shows that a and b do in fact have the same address.

rst