C doubt- union

  • Thread starter sangeeta chowdhary
  • Start date
S

sangeeta chowdhary

#include<stdio.h>
Hey friends ,I want to discuss this code

int main()
{
union a
{
int i;
char ch[2];
};
union a u;
u.ch[0]=3;
u.ch[1]=2;
printf("%d %d %d\n",u.ch[0],u.ch[1],u.i);
return 0;
}

Lets suppose int takes 4 bytes,and char takes 1 byte
According to me,4 bytes will be allocated for union,0th byte will be
for ch[0],1st byte will be for ch[1],and 0-3 bytes for int.
Now ch[0] holds- 00000011
and ch[1] holds- 00000010
and in this way u.i should have-00000011 00000010 00000000 00000000

But output of this code is- 3 2 515

Please tell me where I am going wrong?
 
I

Ian Collins

#include<stdio.h>
Hey friends ,I want to discuss this code

int main()
{
union a
{
int i;
char ch[2];
};
union a u;
u.ch[0]=3;
u.ch[1]=2;
printf("%d %d %d\n",u.ch[0],u.ch[1],u.i);
return 0;
}

Lets suppose int takes 4 bytes,and char takes 1 byte
According to me,4 bytes will be allocated for union,0th byte will be
for ch[0],1st byte will be for ch[1],and 0-3 bytes for int.
Now ch[0] holds- 00000011
and ch[1] holds- 00000010
and in this way u.i should have-00000011 00000010 00000000 00000000

Two things:

1) the byte order of an int depends on the machine type. The ordering
you describe is big endian. You are probably using an x86 based
machine, which is little endian (look these up!).

2) the values of the remaining bytes in u.i are undefined, so they could
contain anything.
But output of this code is- 3 2 515

Try changing your print specifier to ""%d %d %x\n" to see the value of i
in hex.
Please tell me where I am going wrong?

Using poor subject lines?
 
I

Ian Collins

1) the byte order of an int depends on the machine type. The ordering
you describe is big endian. You are probably using an x86 based
machine, which is little endian (look these up!).

The order he describes is correct for storage of u.ch[] regardless of
endianness of the machine, it is interpreted in little-endian order by
his printf("%d", u.i). The endianness is not a factor until then.

I didn't say otherwise.
 
S

sangeeta chowdhary

The order he describes is correct for storage of u.ch[] regardless of
endianness of the machine, it is interpreted in little-endian order by
his printf("%d", u.i). The endianness is not a factor until then.

I didn't say otherwise.

Hey guys thanks a lot.
 
B

blmblm

and in this way u.i should have-00000011 00000010 00000000 00000000

The contents of u.i will depend on whether the remaining bytes of the
union are initialized to zero or not. As written, your code produced
3 2 -859045373 in my Microsoft compiler because the contents of the
union was initialized to 03 02 CC CC in debug mode. (little-endian)
But output of this code is- 3 2 515

This is correct for your concept of the contents you outlined. You
must access a union using the same method that you initialized it. It
is an error to input char[] and retrieve int.

Well .... What do you mean here by "error"?

There was a discussion of this sort of thing in a recent thread
with subject line "dereferencing type-punned pointer" [1], and what
I understand from that thread is that C89 makes few if any guarantees
about what happens if you try to reference one member of a union type
after storing into a different member [2], but C99 is somewhat more
explicit about what happens (the bits are reinterpreted, with results
that are implementation-dependent).

[1] Suggestions for better ways of referencing a previous thread
welcome. I guess I could find it in Google's archives and post
a link to -- something?

[2] I'm not quite sure from a quick review of the earlier thread
whether there's an exception if one of the members involved is an
array of "char".
 
B

blmblm

On Sat, 3 Jul 2010 23:50:22 -0700 (PDT), sangeeta chowdhary

and in this way u.i should have-00000011 00000010 00000000 00000000

The contents of u.i will depend on whether the remaining bytes of the
union are initialized to zero or not. As written, your code produced
3 2 -859045373 in my Microsoft compiler because the contents of the
union was initialized to 03 02 CC CC in debug mode. (little-endian)


But output of this code is- 3 2 515

This is correct for your concept of the contents you outlined. You
must access a union using the same method that you initialized it. It
is an error to input char[] and retrieve int.

Well .... What do you mean here by "error"?

A programmer error.

Ah. Well, I'm not sure I agree, though admittedly I can think of
more examples in which one might want to store an int and then
access that memory as an array of char than the other way around.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top