[net.lang.c] unions inside structures

chris@umcp-cs.UUCP (Chris Torek) (01/20/85)

Concerning the problem of ``invented names'':

Suppose you need a structure to hold either a character/font pair, or
an adjustment.  Then you might write

	enum node_type { ntype_char, ntype_adjust };

	struct char_node {
	    char cn_char;
	    char cn_font;
	};

	struct node {
	    enum node_type n_type;	/* is it a char or an adjust? */
	    union {
		struct char_node un_char;/* value if char */
		short un_adj;		/* value if adjust */
	    } n_un;
	};

(Note the ``invented name'' n_un.)

Then a reasonable compromise for accessing the fields of a struct node
is to create the definitions

	#define n_char	n_un.un_char
	#define n_adj	n_un.un_adj

You can then write

	put(np)
	struct node *np;
	{

		if (np->n_type == ntype_char) {
			select_font(np->n_char.cn_font);
			put_char(np->n_char.cn_char);
		}
		else
			do_adj(np->n_adj);
	}

which makes the ``n_un.un'' part of each name vanish.  Admittedly
this has problems, but it can improve readability---and it requires
no changes to the language.
-- 
(This line accidently left nonblank.)

In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

kpmartin@watmath.UUCP (Kevin Martin) (01/22/85)

In article <2606@umcp-cs.UUCP> chris@umcp-cs.UUCP (Chris Torek) writes:
>Concerning the problem of ``invented names'':
>Suppose you need a structure to hold either a character/font pair, or
>an adjustment.  Then you might write
>
>	enum node_type { ntype_char, ntype_adjust };
>
>	struct char_node {
>	    char cn_char;
>	    char cn_font;
>	};
>
>	struct node {
>	    enum node_type n_type;	/* is it a char or an adjust? */
>	    union {
>		struct char_node un_char;/* value if char */
>		short un_adj;		/* value if adjust */
>	    } n_un;
>	};
>
>Then a reasonable compromise for accessing the fields of a struct node
>is to create the definitions
>
>	#define n_char	n_un.un_char
>	#define n_adj	n_un.un_adj
>
>which makes the ``n_un.un'' part of each name vanish.  Admittedly
>this has problems, but it can improve readability---and it requires
>no changes to the language.

The problem with this is that the fake element names 'n_char' and 'n_adj'
have a scope which differs from that of any other struct elements. That is,
the element names 'n_type', 'n_un', 'un_adj', etc. are only recognized when
preceded by 'primary.' or 'pointer->', where the primary or pointer is of the
appropriate type. On the other hand, 'n_char' and 'n_adj' cannot be used
in any *other* context (unless you happen to have a variable called 'n_un'
which happens to be a struct or union...).
 
The other problem is that a symbolic debugger would have no idea what
p->n_adj means.
                     Kevin Martin, UofW Software Development Group