On 8/4/07, Anup Joshi <[EMAIL PROTECTED]> wrote:
> thank you all of you for your responses but i still cant get one thing, i was
> successfully able to compile my recent code on gcc v3.42 also, here is the
> code again:
>
> =====
> #include <stdio.h>
>
> union vals {
> unsigned short x;
> unsigned char y[2];
> } myvals;
>
> int main() {
> myvals.y[0] = 1; //lsb
> myvals.y[1] = 21; //msb
>
> printf("%d", myvals.x);
> printf("\n %d", sizeof(myvals));
> }
>
> compiled using command: gcc union.c -o myunion.exe
> ====
> and output again is
> 5377
> 2
> =====
> so according to Vic i havent solved the endian problem but i cant understand
> where the problem actually is in this code ???
You should try googling on endianess. x is a 16 bit number an y refers
to two consecutive 8 bit numbers. Now say that we have two machines,
both with 32 bit word length. One is little endian, which means that
the least significant bit (or byte really) is stored first, and one is
big endian, which means that the most significant bit is stored first.
First here means the byte stored at memory offset 0.
If we store a 32 bit number (that is we do a 32 bit write to memory)
endianess does not matter. But when we perform half-word or byte
accesses to memory things will be different.
First we need to look at how the bytes within a word are organized. On
a little endian system a 32 bit number will be stored as:
Byte3 Byte2 Byte1 Byte0
and on a big endian system the same number will be organized as:
Byte0 Byte1 Byte2 Byte3
Byte0 refers to the byte at offset 0, byte1 at the byte at offset 1,
and so on. On a big endian system Byte0 will contain the eight most
significant bits and on a little endian system Byte0 will contain the
eight least significant bits. Remeber that endianess in this case does
not concern us if we only write 32-bit numbers. If we write byte0-3 in
one access the result will be the same, the number will be organized
as MSB downto LSB. However, this is not true when we perform other
accesses:
In your example you store two bytes and then read them back with a
half-word (16 bit, as you do when you read x) access. So you store the
value 1 at offset 0 and the value 21 at offset 1. And now you have:
0b-------- 0b-------- 0b00010101 0b00000001 (little endian format)
0b00000001 0b00010101 0b-------- 0b-------- (big endian format)
('-' here is an undefined bit, we have not touched the bits marked as '-').
remeber, offset 0 in little endian is at the right-most byte and
offset 0 in big endian format is to the left. Now we read a 16 bit
number starting at offset 0. In little endian we get:
0b0001010100000001 = 5377 (in decimal)
and on a big endian system we get:
0b0000000100010101 = 277 (in decimal)
so, you see the comment in your program is wrong on a big endian
system, y[0] will write the MSB.
>
> second thing is the sizeof union shows up to be 2 but i was expecting it to
> be 3 (i thought the array is of 3 bytes though it may contain only two
> elements) because i changed the array from uchar y[1](sizeof gave 2) to
> uchar y[2](size 2 again)!!!! why does this happen???
unsigned char y[2]; will give you an array with two elements. The
first element is at y[0] and the second is at y[1]. If you access y[2]
you are out of bounds.
Hope that helped,
Jan