Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ncar!tank!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.std.c Subject: Re: casting structs Message-ID: <18921@mimsy.UUCP> Date: 7 Aug 89 04:52:18 GMT References: <9184@chinet.chi.il.us> Distribution: usa Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 77 In article <9184@chinet.chi.il.us> kdb@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@mimsy.umd.edu Path: uunet!mimsy!chris