casting structs

Karl Botts kdb at chinet.chi.il.us
Tue Aug 8 16:15:24 AEST 1989


In article <18921 at mimsy.UUCP> chris at mimsy.UUCP (Chris Torek) writes:
>>... 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.

The array business is beyond me -- there are no arrays in sight anywhere
here.  Obviously, what I want is a bit struct as will in fact be generated
by the perfectly legit line:

x_t x = { 1, 2, 5};

and an int which is a bitwise copy of the first sizeof(int) bytes of the
struct.  I made no request for any machine independence -- bit fields are
never machine independent, and while this may diminish their usefulness it
does not eliminate it.

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

In the first place, perhpas the most important principal of "the spirit of
C" is that the question is never "why?", but "why not?"  In the absence of
a compelling reason to the contrary, a programmer should never be
inhibited by the lack of omniscient foresight of the language comittee, or
protected from his own folly, by being prohibited from doing anything in C
that can be done in assembler language, including machine specific
assembler language.

In the second place, this question came to my mind not as mere speculation,
but because I had a problem.  I had occassion to initialize a large table
of structs, some of whose fields were ints which might or might not be
broken into bit fields, depnding on the values of other fields of the
table.  This was in connection with a parser for a peculiar language.  For
instance, some entries in the table represented function names, and some
represented operators -- the same integer field would contain a different
set of bit fields if the token was a function name than if it were an
operator name.  It would be most convenient, readable and maintainable to
initialize the table all in one place.  I do not care what particular
values the bit fields produce as an int, so long as I can get the bit
fields when I need them.

Now, if I make two bit field structs and make the integer field in the table
struct a union of them, I can only initiaize one of them.  I already had a bunch
of bit fiddling macros -- stuff like MID_BITS_SET(i, m n) and so forth.  So
I built some macros to refer to the bit fields -- I suspect this is the way
it used to be done, until somebody thought of bit fields.  It made the
table big and messy, but it worked -- until I tried to compile it!  It
seems tha macros were too big to expand, and that an arbitrary limit of 509
characters on the length of macro expansions is endorsed by the ANSI
standard!

So, I wanted to do what I said in my previous message -- initialize the
bitfields in special structs for the purpose, ancd cast them, all in the
same initializer, into an int (or whatever).  I ask again --why can't I do
this?

protected
from his 



More information about the Comp.std.c mailing list