[net.lang.c] Explicit union initializers, a sample tough case.

kpmartin@watmath.UUCP (Kevin Martin) (11/05/84)

>Jim Balter, INTERACTIVE Systems writes:
>I suggest that if an initializer of a union has no explicit cast, it be
>converted to the type of the first member, otherwise it has an explicit
>content which should become the content of the union, provided it is
>type-compatible with at least one member of the union.  The default case
>guarantees that this is at least as powerful as "initialize first member".
>It is unambiguous, it is complete if it is recognized that (char *)"abc" and
>(char [])"abc" produce different "values", and it is compatible in form with
>the existing language.
>
I agree that if the element ISN'T specified, that the first one should be
assumed.

The following case demonstrates that initializing a selected union
element requires a language extension:
	typedef union {
		struct x1 {
			unsigned a;
			unsigned b;
			unsigned c;
		} big;
		struct x2 {
			unsigned a:4;
			unsigned b:4;
			unsigned c:4;
		} small;
	} blarto;

There are several choices, including:
1) Not allow the thing to be initialized because it is a union (the
   current situation).
2) Not allow ths thing to be initialized because it is a union of structures.
3) Only allow initialization of the first element (e.g. 'big').
4) Extend the syntax etc. to allow casting of aggregate constants, e.g.
	blarto var = (struct x2) { 1, 2, 3 };
5) Extend the syntax etc. to allow the element to be named, e.g.
	blarto var = small = { 1, 2, 3 };

1) Is the problem that we all want to correct.
2) Is a silly restriction.
3) Is a solution, but it doesn't help when you have several variants
   of a union you want initialized.
4) Barely works, but I can't say I like it.
5) Also works, and I prefer it, since the code actually says what I
   want to do (e.g. "initialize the element called 'small' with ..." rather
   than "Find a (struct x2) somewhere in this union, and initialize
   it with ...")

Both (4) and (5) require some extensions to the current language. Either
could default to the first element if no element is specified.
(4) also has the quirk that the expressions 1 and (int)1 are no longer
equivalent, if one of them is used to initialize a union which has an 'int'
member but the first member is not an 'int'.

>What is wrong with
>	union foo thing.member = {...};
>?  It is clear and unambiguous.
	struct {
		union {
			type_1 x;
			type_2 y;
		} onion;
		type_3 a;
	} var = { /* Try filling this space*/ };

(With name-the-element, the last line becomes:
	} var = { { y = 5 }, 42 };	/* {}'s can be omitted */
)
                Kevin Martin, UofW Software Development Group