Welcome to Dream.In.Code
Getting C++ Help is Easy!

Join 132,672 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 1,171 people online right now. Registration is fast and FREE... Join Now!




Unions

 
Reply to this topicStart new topic

Unions, Explian the behaviour

harshakirans
post 31 Aug, 2007 - 08:48 AM
Post #1


D.I.C Head

Group Icon
Joined: 26 Apr, 2006
Posts: 107



Dream Kudos: 150
My Contributions


CODE
#include <stdio.h>
main()
{
    typedef union
    {
        int a;
        char b[10];
        float c;
    }
    Union;

    Union x,y = {100};
    x.a = 50;
    strcpy(x.b,"hello");
    x.c = 21.50;

    printf("Union x : %d %s %f \n",x.a,x.b,x.c );
    printf("Union y :%d %s %f \n",y.a,y.b,y.c);
}



The output is: Union x : 0 21.500000
Union y : 100 d 0.000000

Here please explain the output behaviour.

This post has been edited by harshakirans: 31 Aug, 2007 - 08:51 AM
User is offlineProfile CardPM

Go to the top of the page

Bench
post 31 Aug, 2007 - 09:14 AM
Post #2


D.I.C Addict

Group Icon
Joined: 20 Aug, 2007
Posts: 602



Thanked 10 times

Dream Kudos: 150

Expert In: C/C++

My Contributions


Put simply, its undefined behaviour. You may not assign a value to one member of a union and then expect to read that value from another union member. (Though there are some notable exceptions when using unsigned char to examine the bit representation of another member)

This post has been edited by Bench: 31 Aug, 2007 - 09:16 AM
User is offlineProfile CardPM

Go to the top of the page

GWatt
post 31 Aug, 2007 - 09:38 AM
Post #3


human inside

Group Icon
Joined: 1 Dec, 2005
Posts: 2,162



Thanked 16 times

Dream Kudos: 450
My Contributions


You can define a single variable to have several different data types.
CODE
typedef union
{
    double d;
    int[sizeof(double) / sizeof(int)] i;
    char[sizeof(double)] c;
} Union;


The double, int array, and char array all share the same address in memory. This can be useful, because you can look at each byte in a data type. A char is one byte, an int is 4, and a double is 8.
User is offlineProfile CardPM

Go to the top of the page

Amadeus
post 31 Aug, 2007 - 09:46 AM
Post #4


g++ -o drink whiskey.cpp

Group Icon
Joined: 12 Jul, 2002
Posts: 12,178



Thanked 33 times

Dream Kudos: 25
My Contributions


Not sure how that relates to the user's question....
User is online!Profile CardPM

Go to the top of the page

Bench
post 31 Aug, 2007 - 10:11 AM
Post #5


D.I.C Addict

Group Icon
Joined: 20 Aug, 2007
Posts: 602



Thanked 10 times

Dream Kudos: 150

Expert In: C/C++

My Contributions


QUOTE(GWatt @ 31 Aug, 2007 - 06:38 PM) *
A char is one byte, an int is 4, and a double is 8.
That's wrong I'm afraid - The only guarantee you have is that sizof(char) == 1. The rest is entirely platform dependent.
The only guarantee available is that sizeof(int) is at least the same as sizeof(short) - which, in turn is at least the same as sizeof(char). For sizeof(double), the only requirement is that its at least as large as sizeof(float)

Also, your union example doesn't fit your description. both int and char may be signed, and are subject to "trap" values. If you wanted to manipulate the bit representation of a double (or any data type) using a union, then the only reliable way is with unsigned char

This post has been edited by Bench: 31 Aug, 2007 - 10:13 AM
User is offlineProfile CardPM

Go to the top of the page

harshakirans
post 1 Sep, 2007 - 01:05 AM
Post #6


D.I.C Head

Group Icon
Joined: 26 Apr, 2006
Posts: 107



Dream Kudos: 150
My Contributions


Omg !!! my question is ....

I gave a piece of code

I have the answer written

Can anyone explain me how did the compiler process the code to get those answers.
User is offlineProfile CardPM

Go to the top of the page

Bench
post 1 Sep, 2007 - 01:44 AM
Post #7


D.I.C Addict

Group Icon
Joined: 20 Aug, 2007
Posts: 602



Thanked 10 times

Dream Kudos: 150

Expert In: C/C++

My Contributions


QUOTE(harshakirans @ 1 Sep, 2007 - 10:05 AM) *

Omg !!! my question is ....

I gave a piece of code

I have the answer written

Can anyone explain me how did the compiler process the code to get those answers.
No, i'm afraid we simply can't because its undefined behaviour - Meaning that anything could have happened. With that in mind, there's really not much point knowing what your particular version of your particular compiler actually did, because you cannot rely on undefined behaviour. If you take your code to a different compiler or platform then something else entirely different could happen.

If you really want to know what your compiler did, then the only way is to look in some detail at the compiler's documentation for clues.
User is offlineProfile CardPM

Go to the top of the page

harshakirans
post 1 Sep, 2007 - 01:52 AM
Post #8


D.I.C Head

Group Icon
Joined: 26 Apr, 2006
Posts: 107



Dream Kudos: 150
My Contributions


QUOTE(Bench @ 31 Aug, 2007 - 10:14 AM) *

Put simply, its undefined behaviour. You may not assign a value to one member of a union and then expect to read that value from another union member. (Though there are some notable exceptions when using unsigned char to examine the bit representation of another member)



Here the value is assigned to y (y={100})

and x.a is initialized to 100
x.b to hello
x.c to 21.5


wel y behavoiur may be undefined but wat happened to values in x.

CAn u please explain in detail.
User is offlineProfile CardPM

Go to the top of the page

1lacca
post 1 Sep, 2007 - 03:45 AM
Post #9


code.rascal

Group Icon
Joined: 11 Aug, 2005
Posts: 3,822



Thanked 11 times
My Contributions


I see no undefined behaviour here.
The members of an union occupy the same memory space, so generally it contains only the most recent value - and tryin to read something that is not the currently set element will generate a cast. That's why when 100 is set into y as an int, the following is printed:
"100" because no conversion is needed, I think no explanation is needed here
"d" because: 100 is the lower byte of the integer the ASCII code of the letter d, and the upper byte is 0 that terminates the string.
"0.0000" is the 100 int cast into a float, this would need a bit more explanation, but it can be demonstrated easily. (actually some undefined behaviour might be found here)

I think I've provided every information needed to find out how the output for x is generated now.
User is offlineProfile CardPM

Go to the top of the page

Bench
post 1 Sep, 2007 - 03:46 AM
Post #10


D.I.C Addict

Group Icon
Joined: 20 Aug, 2007
Posts: 602



Thanked 10 times

Dream Kudos: 150

Expert In: C/C++

My Contributions


QUOTE(harshakirans @ 1 Sep, 2007 - 10:52 AM) *

QUOTE(Bench @ 31 Aug, 2007 - 10:14 AM) *

Put simply, its undefined behaviour. You may not assign a value to one member of a union and then expect to read that value from another union member. (Though there are some notable exceptions when using unsigned char to examine the bit representation of another member)



Here the value is assigned to y (y={100})

and x.a is initialized to 100
x.b to hello
x.c to 21.5


wel y behavoiur may be undefined but wat happened to values in x.

CAn u please explain in detail.
As someone else already mentioned, all variables in a union occupy the same space in memory. Which means that when you use one, other variables in that union are effectively invalid. (The compiler won't stop you accessing them, but they will be invalid as far as their content is concerned)

When you assign 'x.c' a value of 21.5, you've overwritten or invalidated some or all of what was in the union before. After this, any attempt to read x.a or x.b could result in anything happening. Also, the size of a union is always equal to the size of that union's largest member. Other, smaller members of the union are often "padded" in memory so that they are still usable. but there is no set requirement for how or where this padding may exist, so there is no way to predict how union members may affect each another.

Again, the only exception to all this is when you combine a variable, and an array of unsigned char, whose length is equal to the size of that variable, then you can reliably use the array of unsigned char to examine the bit-pattern of that variable.



Edit-Corrected a typo

This post has been edited by Bench: 1 Sep, 2007 - 03:56 AM
User is offlineProfile CardPM

Go to the top of the page

Reply to this topicStart new topic
Time is now: 11/23/08 06:06AM

Live C++ Help!

C++ Tutorials

Reference Sheets

C++ Snippets

Bye Bye Ads

Free DIC T-Shirt

T-Shirt Example

Related Sites

Monthly Drawing

Thumb Drive

Partners

Top Contributors

Top 10 Kudos This Month