Initialization of unions under ANSI C

Hokey hokey at plus5.UUCP
Thu Oct 25 02:02:27 AEST 1984


> < Note that there is no ambiguity even when initializing a list of items
> < inside a union: the initializer-list could be cast, or the first element
> < of the list could be cast.
> 
> Dennis himself pointed out immediately this example when given the above
> argument a year and a half ago at a standards meeting:
> 
> union {
>     char *x;
>     char y[4];
>     } = "abc";
> 
> The string "abc" can represent either a character string to initialize the
> array y or it can represent a character pointer to represent the pointer x,
> depending on the context. Considering that both contexts are valid in this
> place, some rule is necessary. The rule of "first listed in the union"
> would mean that it would initialize the pointer. If you wanted the array
> initialized, how would you specify it with casts? There is no way currently,
> but it is easy to do with ANSI C by just listing the array first.
> 
> 					Tony Hansen
> 					pegasus!hansen

So cast it. (No hidden pun...)  Use this instead:

union {
    char *x;
    char y[4];
    } Strange[] = {
	(char[]) "abc",		/* This is an array of characters (y) */
	(char *) "abc"		/* This is a pointer to a character */
    };

Did you read the last comment above?  All (char *) does is "permit" one
to reference the object to which it points *as a character*.  There is
no guarantee regarding the veracity of the object "at the end of the rainbow"
or the objects surrounding the item referenced by the pointer.  Do I need
to go on about this point?

As near as I can tell, initialization of tables is the biggest pain.  These
tables need to be initialized to useful data.  I would hate to see a portion
of a table initialized at compile time and the rest of it initialized at
run time!  I, for one, would rarely bother to initialize unions at compile
time because I almost always want the union portions of the tables filled
with data befitting the table entry.  The proposed initialization rule
seems weak to me.

Both replies to my posting were cases where there was an ambiguity in the
interpretation of the initializer (the other reply asked about the case in
which a union of an int and a float was initialized to "2").

I am one of those apparently rare people who explicitly declares or casts
Everything.  (Well, almost.  I usually specify the "length" to malloc, read,
and write using an int because I never let the data lengths get that big;
the data in these cases is invariably string, and all the string functions
use ints.)  I wish the C compiler would help people like me, and warn me
about implicit declarations and conversions.  I don't care if I have to add
a switch to CFLAGS (although I would prefer strict checking as the default,
and make the lazy people specify a switch to provide "lax" checking).

Explicit declarations seem to solve the problem of arbitrary initialization
of unions.  Could somebody point out an example where casting initializers
won't work?
-- 
Hokey           ..ihnp4!plus5!hokey
		  314-725-9492



More information about the Comp.lang.c mailing list