[comp.lang.c] Unions and structures in C

asjoshi@phoenix.Princeton.EDU (Amit S. Joshi) (01/23/88)

Hello,

I have a question about unions and structures in C:
Suppose I have the following fragment of a program :

struct one { float x,y; };

union two { float x[2]; 
	    struct one one; };

main () {
	union two two;

	two.one.x = 1.0; two.one.y = 2.0;
	printf(" x = %f,  y = %f\n",two.one.x,two.one.y);
	printf(" x[%d] = %f, x[%d] = %f\n",1,two.x[0],2,two.x[1]);
}
My question is what would the second printf statement print ?
Would I get "x[1] = 1.0, x[2] = 2.0" or "x[1] = 2.0, x[2] = 1.0" or
would I get that two.x[?] is undefined ? Or what? Does the order in
which the the elements of the structure are present correspond to the 
other elements declared in the union ? Is any such correspondence
guaranteed ? I know from some test cases that in TurboC I seem to get a
correspondence between the parts of the union.   

The reason I need this is that if the order or correspondence were known
then I could use very informative names in the structure and use arrays
where array processing is more efficient, e.g. suppose x and y were the
coordinates of an object then using x and y for code where there is a
distinction between the axes is nice whereas when I want to say
calculate the motion I might wish to integrate where the array
representation is more convinient.

Thanks,


-- 
Amit Joshi	BITNET	|	Q3696@PUCC.BITNET
		USENET	| {seismo, rutgers}\!princeton\!phoenix\!asjoshi
"There's a pleasure in being mad... which none but madmen know!" - St.Dryden

steve@aardvark.UUCP (Steve Willoughby) (01/30/88)

In article <1520@phoenix.Princeton.EDU> asjoshi@phoenix.Princeton.EDU (Amit S. Joshi) writes:
>Hello,
>
>I have a question about unions and structures in C:
>Suppose I have the following fragment of a program :
>
>struct one { float x,y; };
>union two { float x[2]; 
>	    struct one one; };
>main () {
>	union two two;
>	two.one.x = 1.0; two.one.y = 2.0;
>	printf(" x = %f,  y = %f\n",two.one.x,two.one.y);
>	printf(" x[%d] = %f, x[%d] = %f\n",1,two.x[0],2,two.x[1]);
>}
>My question is what would the second printf statement print ?

For the C compilers I have used, the second printf statement 
would be the same as the first, i.e.,
	x = 1.0,  y = 2.0
	x[1] = 1.0, x[2] = 2.0
Supposedly, the members of a union should line up like you expect
here (as long as you don't create any alignment problems, which
I don't think you would with the float's here).

You should create a memory area that looks like this:
	.___.___.___.___.___.___.___.___.
	| first_float   | second_float  |
	|___.___.___.___|___.___.___.___|

	   "two.x[0]"       "two.x[1]"	-- two floats called x
	   "two.one.x"      "two.one.y" -- two floats called x and y

Lattice C does something like this for defining CPU registers
as a union of two identically-sized structures; one structure
defines registers as chars (individual bytes addressable), while
the other defines regs as ints (addressable in two-byte pairs).
You can freely mix the two -- assign values to some members as
ints and others as chars (each time using the appropriate union
member).  This works because the union members match up exactly.

There could be some structs that won't behave so nicely (again,
if you've got things in them that need to be padded out to word
boundaries or such).

-- 
"I am always doing what I cannot do yet, in order to learn how to do it."
		-- Vincent van Gogh

Steve Willoughby (UUCP: ...!ihnp4!tektronix!tessi!aardvark!steve)