[comp.unix.questions] Illegal union question

jms@wzlr.UUCP (Jack Stephens) (02/23/89)

The following declaration yeilds an "illegal member use" error
for both f and next under the compilers on both by PC and my 3B1 
and I can't seem to understand why.  Amybody feel pedegogical ?

jms

typedef struct m_i {
  int type;
	 union {
	 int (*f)();
	 struct m_i *next;
	 }
} menu[10];

debra@alice.UUCP (Paul De Bra) (02/26/89)

In article <833@wzlr.UUCP> jms@wzlr.UUCP (Jack Stephens) writes:
>
>The following declaration yeilds an "illegal member use" error
>for both f and next under the compilers on both by PC and my 3B1 
>and I can't seem to understand why.  Amybody feel pedegogical ?
>
>jms
>
>typedef struct m_i {
>  int type;
>	 union {
>	 int (*f)();
>	 struct m_i *next;
>	 }
>} menu[10];

Aha, different compilers have a different opinion on this one.
First of all, whether the definition is correct or not, the union needs
a name, thus
	union {
	...
	} name_of_union;

This is a nuisance because one must access fields like
mymenu[5].name_of_union.next instead of mymenu[5].next
However, one can have several unions inside the same struct, and such a
union may have fields with names that also appear in some other union.

Some compilers accept your declaration, some others want at least a ';'
after the } that ends the union, but in either case there is no way to
access the fields of the union by name.

Paul.
-- 
------------------------------------------------------
|debra@research.att.com   | uunet!research!debra     |
------------------------------------------------------

gwyn@smoke.BRL.MIL (Doug Gwyn ) (02/26/89)

In article <833@wzlr.UUCP> jms@wzlr.UUCP (Jack Stephens) writes:
>The following declaration yeilds an "illegal member use" error
>for both f and next under the compilers on both by PC and my 3B1 
>and I can't seem to understand why.  Amybody feel pedegogical ?
>typedef struct m_i {
>  int type;
>	 union {
>	 int (*f)();
>	 struct m_i *next;
>	 }
>} menu[10];

This is a C question, not a UNIX question.

It's a small miracle that the compiler accepted the declaration,
which is missing a semicolon after the first }.

The real problem is that you need to name the union member of the
structure and use its name as part of the chain of member names to
reach the innards of the union.  For example:

	typedef struct m_i
		{
		int		type;
		union	{
			int		(*f)();
			struct m_i	*next;
			}	u;
		}	menu[10];
	/* ... */
	extern menu	root_menu, *make_menu();
	menu		*x = make_menu( &root_menu );
	int		i = get_selection( x );
	while ( (*x)[i].type != 0 )
		{
		x = make_menu( (*x)[i].u.next );
		i = get_selection( x );
		}
	(*(*x)[i].u.f)( x, i );