casting structs

Chris Torek chris at mimsy.UUCP
Mon Aug 7 14:52:18 AEST 1989


In article <9184 at chinet.chi.il.us> kdb at chinet.chi.il.us (Karl Botts) writes:
>Why is it utterly illegal to cast a struct (or a union) to anything?

The major reason is that casts are, in C, operators that take a single
input value, perform some transformation, and produce a single output
value.  It seems relatively simple to recursively apply such an
operator to an aggregate, so that one could, by casting an aggregate,
apply the same transformation to each element of that aggregate,
producing a new aggregate.  However, you seem to want something that
will apply some transform to an aggregate, yeilding a single value:

>... For instance:
>
>typedef struct X_T {
>	unsigned a : 1;
>	unsigned b : 2;
>	unsigned c : 3;
>} x_t;
>
>x_t x = { 1, 2, 5};
>int i = (int)x;
>
>seems quite sensible to me.  

To me, it seems sensible for (int)x to produce as its result an object
of type `array 3 of int' whose value is {1, 2, 5}.  C, however, does
not have any array rvalues now; this sort of change goes much deeper
than it might first appear.

Exactly what value you want from your transform is not clear to me,
nor do I know how one would go about defining this in a reasonably
efficient, yet machine-independent manner.

>Of course, you can acheive the desired effect here by replacing the last
>line of the above with:
>
>int i = *(int *)&x;
>
>but this strikes me as unnecessary obfuscation

The whole thing strikes me as rather obfuscated.  The value of `i'
produced by *(int *)&x is completely different on a VAX than on a
Tahoe, because the two compilers allocate bits in the opposite orders:

	[vax218] cc -o z z.c		# (this window has been around
	[vax219] ./z			# for a while . . .)
	i=45
		.
		.
		.
	[tahoe1] cc -o z z.c
	[tahoe2] ./z
	i=-738197504

Identical source code; I just added a `main' and a `printf' to your
example above.

Incidentally, since compilers are free to allocate bitfields in any
order, and there is no true `natural' order on 68020s, different
compilers for the same machine will yeild different results.

>(but no additional overhead, at least on the compilers I have traced
>through the output of similar code for -- they can figure out that no
>real pointer operations are required here.)

Indeed; all that is required is machine-dependent operation, and the
pointer cast makes it clear that something machine-dependent is happening.
(With a few exceptions, all pointer casts involve machine-dependent
transformations.)

>What would be really nice would be a way to initialize an int, say, by
>using a struct.

Why?
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.std.c mailing list