casting structs

Karl Botts kdb at chinet.chi.il.us
Sun Aug 6 18:32:18 AEST 1989


Why is it utterly illegal to cast a struct (or a union) to anything?
Obviously, this would be a capability susceptible to abuse;
nevertheless, it is not in the "spirit of C" do ban something for that
reason only.  In fact there are cases -- particularly involving bit
structs, but it is possible to hypothesize case for other structs as well
-- when casting a struct seems perfectly reasoable.  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.  

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 (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.)

What would be really nice would be a way to initialize an int, say, by
using a struct.  It is perfectly legal to initialize a value by casting
another type of value into the type desired, as in:

long l = (long)&foo;

where foo can be any lvalue.  So why isn't it legal for a non-scalar type?

The only reason I can come up with is that it won't fit into the syntax --
at least I can't come up with anything that seems sensibel and would work.
How would you wirte what I _really_ want to do in the first example?

int i = (int)x_t x = {1, 2, 5};

Whoops, that's no good (even if the compiler would accept it) -- it defines
a data object "x", just like the first example.  So lets leave x out:

int i = (int)x_t = {1, 2, 5};

Hey, wait a minute, maybe that _does_ work.  Suppose we stipulated that
initializing a type name, as opposed to an object of that type, produces an
rvalue of the specified type and value, rather than an lvalue.  This
wouldn't break any code, because initializeing a type name is simply
illegal now.

Hmmm..  The next question is, is the above an LALR parse?  I can't see any
reason why not, off the top of my head.  If the type name was compound, you
might have to put perens around it as in:

int i = (int)(struct X_T) = {1, 2, 5};

I must think about this...



More information about the Comp.std.c mailing list