Union In C

C

chang

Hi All,
have some experience in C prog language. I have small doubt abt
using unions in C language.
Here is a small programm in vc++:

union a{
int b;
char c;
}d;

int main () {
d.b=360;
d.c=1;
printf("%d %d ",d.b ,d.c,);
}

In union largest sized member memory is reserved by union .

but for a sake if i declare this way then i've seen the d.b value is
showing 257 in output window and if i declare d.b =255 or below 255
that then it is showing the what is last defined for d.c, means value
is =1 for all variables.
So Here for first time how the memory is overwritten?
Please let me know on this . I am looking forward to you .

Thanks
Chinmoy
 
S

Spade

Hi All,
 have some experience in C prog language. I have small doubt abt
using unions in C language.
Here is a small programm in vc++:

union a{
         int b;
         char c;

}d;

int main () {
d.b=360;
d.c=1;
printf("%d %d ",d.b ,d.c,);

}

In union largest sized member memory is reserved by union .

but for a sake if i declare this way then i've  seen  the d.b value is
showing 257 in output window and if i declare d.b =255 or below 255
that then it is showing the what is last defined for d.c, means value
is =1 for all variables.
So Here for first time how the memory is overwritten?
Please let  me know on this . I am looking forward to you .

IIRC, you are only allowed to access the value of union member which
was last being assigned with a value. This is definitely unspecified
behaviour, if not undefined. Because the size of integer is not fixed.

Spade.
 
M

Martien Verbruggen

Hi All,
have some experience in C prog language. I have small doubt abt
using unions in C language.
Here is a small programm in vc++:

union a{
int b;
char c;
}d;

int main () {
d.b=360;
d.c=1;
printf("%d %d ",d.b ,d.c,);
}

You can only access the value of the member you set last for a union.
So, if you set d.b, you can only read the value of d.b. Once you've
assigned something to d.c, you should no longer read the value of d.b
[1].

You also need to #include <stdio.h> when you use printf().

Strictly speaking, the behaviour of the above program is undefined, and
therefore anything could happen.
In union largest sized member memory is reserved by union .

The size of the union is _at least_ the size of its largest member. It
can be larger.
but for a sake if i declare this way then i've seen the d.b value is
showing 257 in output window and if i declare d.b =255 or below 255
that then it is showing the what is last defined for d.c, means value
is =1 for all variables.
So Here for first time how the memory is overwritten?
Please let me know on this . I am looking forward to you .

next time, please simply write a program with inputs and outputs, rather
than trying to describe it in words. Programs and data are easier to
read and understand.

The members of a union share the same storage space. it is not entirely
clear from your post that you understand that. So, when you write to
one member, and then (incorrectly) access another member, the value that
you get back is potentially nonsensical. The system will try to
interpret the bit pattern in that location in a manner likely to be
incompatible with what was stored.

\begin{offtopic}

Assume your int is 16 bits (the same holds for a 32 bit int, but I don't
want to hape to type 16 extra zeroes.). The bit pattern for 360 would
be:

00000001:01101000

Because your platform is little endian, that would live in memory like
this:

01101000:00000001

Now you write to the char member of the union. The char is 8 bits, and
stored in the same _first_ 8 bits in the above pattern. You will store 1
in there, ending up with:

00000001:00000001

Then you go and read this as an int again, ending up with the value 257.

Note that on a bigendian system the result will be wildly different,
which is one of the main reasons you need to not do this.

\end{offtopic}


Martien

[1] There are some special exceptions to this, but they do not apply
here.
 
S

s0suk3

Hi All,
 have some experience in C prog language. I have small doubt abt
using unions in C language.
Here is a small programm in vc++:

union a{
         int b;
         char c;

}d;

int main () {

As Twink would say: "Oh dear, you've done it now..."
d.b=360;
d.c=1;
printf("%d %d ",d.b ,d.c,);

}

In union largest sized member memory is reserved by union .

but for a sake if i declare this way then i've  seen  the d.b value is
showing 257 in output window and if i declare d.b =255 or below 255
that then it is showing the what is last defined for d.c, means value
is =1 for all variables.
So Here for first time how the memory is overwritten?

Your description of the output suggests that your machine stores data
in little-endian order. Let's see how the union is stored, assuming
that 'int's occupy four bytes:

____________________________________________________
| | |
| Member | Bytes |
|________|___________________________________________|
| | | | | |
| .b | 00000000 | 00000000 | 00000000 | 00000000 |
|________|__________|__________|__________|__________|
| | | | | |
| .c | 00000000 | | | |
|________|__________|__________|__________|__________|

That would be the union set to all-bits-zero. Now, when the statement
'd.b = 360;' is executed, the union will look like this:

____________________________________________________
| | |
| Member | Bytes |
|________|___________________________________________|
| | | | | |
| .b | 00000100 | 00000001 | 00000000 | 00000000 |
|________|__________|__________|__________|__________|
| | | | | |
| .c | 00000100 | | | |
|________|__________|__________|__________|__________|

The number 360 has the binary representation 100000100 (those are 9
bits), which occupies more that one byte. Since the machine is little-
endian, the '1' bit at the left will appear as the right-most bit of
the "second byte".

And when the statement 'd.c = 1;' is executed, it will look like this:

____________________________________________________
| | |
| Member | Bytes |
|________|___________________________________________|
| | | | | |
| .b | 00000001 | 00000001 | 00000000 | 00000000 |
|________|__________|__________|__________|__________|
| | | | | |
| .c | 00000001 | | | |
|________|__________|__________|__________|__________|

The number 1 looks the same in decimal and in binary. So, the
statement 'd.c = 1;' has changed the first byte of d.b, but not the
second, which retains a '1' bit for its right-most bit.

At this point, d.b has the binary representation 100000001, and that's
why you're seeing 257 when you print d.b -- 100000001 is 257 in
decimal.

And the reason you get the "expected" values if you assign the number
255 or below to d.b is that 255 can be represented using only one byte
(255 is 11111111 in binary; any number higher than that would require
at least two bytes, and would mess up the union).

Sebastian
 
S

s0suk3

As Twink would say: "Oh dear, you've done it now..."



Your description of the output suggests that your machine stores data
in little-endian order. Let's see how the union is stored, assuming
that 'int's occupy four bytes:

  ____________________________________________________
 |        |                                           |
 | Member |                   Bytes                   |
 |________|___________________________________________|
 |        |          |          |          |          |
 |  .b    | 00000000 | 00000000 | 00000000 | 00000000 |
 |________|__________|__________|__________|__________|
 |        |          |          |          |          |
 |  .c    | 00000000 |          |          |          |
 |________|__________|__________|__________|__________|

That would be the union set to all-bits-zero. Now, when the statement
'd.b = 360;' is executed, the union will look like this:

  ____________________________________________________
 |        |                                           |
 | Member |                   Bytes                   |
 |________|___________________________________________|
 |        |          |          |          |          |
 |  .b    | 00000100 | 00000001 | 00000000 | 00000000 |
 |________|__________|__________|__________|__________|
 |        |          |          |          |          |
 |  .c    | 00000100 |          |          |          |
 |________|__________|__________|__________|__________|

The number 360 has the binary representation 100000100

That's wrong, sorry, I confused 257 with 260. 360 has the binary
representation 101101000, so the union would look like

____________________________________________________
| | |
| Member | Bytes |
|________|___________________________________________|
| | | | | |
| .b | 01101000 | 00000001 | 00000000 | 00000000 |
|________|__________|__________|__________|__________|
| | | | | |
| .c | 01101000 | | | |
|________|__________|__________|__________|__________|

Fortunately, the rest of the post is still valid, since the statement
'd.c = 1;' leaves the first byte as 00000001, and the second byte
remains the same.
(those are 9
bits), which occupies more that one byte. Since the machine is little-
endian, the '1' bit at the left will appear as the right-most bit of
the "second byte".

And when the statement 'd.c = 1;' is executed, it will look like this:

  ____________________________________________________
 |        |                                           |
 | Member |                   Bytes                   |
 |________|___________________________________________|
 |        |          |          |          |          |
 |  .b    | 00000001 | 00000001 | 00000000 | 00000000 |
 |________|__________|__________|__________|__________|
 |        |          |          |          |          |
 |  .c    | 00000001 |          |          |          |
 |________|__________|__________|__________|__________|

The number 1 looks the same in decimal and in binary. So, the
statement 'd.c = 1;' has changed the first byte of d.b, but not the
second, which retains a '1' bit for its right-most bit.

At this point, d.b has the binary representation 100000001, and that's
why you're seeing 257 when you print d.b -- 100000001 is 257 in
decimal.

And the reason you get the "expected" values if you assign the number
255 or below to d.b is that 255 can be represented using only one byte
(255 is 11111111 in binary; any number higher than that would require
at least two bytes, and would mess up the union).

Sebastian
 

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

Staff online

Members online

Forum statistics

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

Latest Threads

Top