Labels

Tuesday, June 8, 2010

use of union 2

http://cplus.about.com/od/learningc/ss/lowlevel_9.htm
1:
The uses of union are few and far between. On most computers, the size of a pointer and an int are usually the same- this is because both usually fit into a register in the CPU. So if you want to do a quick and dirty cast of a pointer to an int or the other way, declare a union.
 union intptr {
int i;
int * p;
};

union intptr x;

x.i = 1000;
*(x.p)=90; /* puts 90 at location 1000 */


2:
Another use of a union is in a command or message protocol where
different size messages are sent and received. Each message type will
hold different information but each will have a fixed part (probably a struct) and a variable part bit. This is how you might implement it..
struct head {
int id;
int response;
int size;
};

struct msgstring50 {
struct head fixed;
char message[50];
}

struct struct msgstring80 {
struct head fixed;
char message[80];
}

struct msgint10 {
struct head fixed;
int message[10];
}

struct msgack {
struct head fixed;
int ok;
}

union messagetype {
struct msgstring50 m50;
struct msgstring80 m80;
struct msgint10 i10;
struct msgack ack;
}

In
practice, although the unions are the same size, it makes sense to only
send the meaningful data and not wasted space. A msgack is just 16
bytes in size while a msgstring80 is 92 bytes. So when a messagetype
variable is initialized, it has its size field set according to which type it is. This can then be used by other functions to transfer the correct number of bytes.
union messagetype ackmsg;
ackmsg.fixed.size = sizeof(msgack) ; /* 16 */

2 comments:

  1. #include

    void main()
    {
    union u_example
    {
    float decval;
    int pnum;
    double my_value;
    } U1;

    U1.my_value = 125.5;
    U1.pnum = 10;
    U1.decval = 1000.5f;
    printf("\ndecval = %f pnum = %d my_value = %lf",
    U1.decval, U1.pnum, U1.my_value );

    printf("\nU1 size = %d\ndecval size = %d pnum size = %d my_value size = %d",
    sizeof U1, sizeof U1.decval, sizeof U1.pnum, sizeof U1.my_value);
    }



    output:
    decval = 1000.500000 pnum = 1148854272 my_value = 125.500016
    U1 size = 8
    decval size = 4 pnum size = 4 my_value size = 8

    ReplyDelete
  2. A union is a variable that may hold (at different times) objects of different types and sizes, with the compiler keeping track of size and alignment requirements. Unions provide a way to manipulate different kinds of data in a single area of storage, without embedding any machine-dependent information in the program. They are analogous to variant records in pascal.

    As an example such as might be found in a compiler symbol table manager, suppose that a constant may be an int, a float, or a character pointer. The value of a particular constant must be stored in a variable of the proper type, yet it is most convenient for table management if the value occupies the same amount of storage and is stored in the same place regardless of its type. This is the purpose of a union - a single variable that can legitimately hold any of one of several types. The syntax is based on structures:

    union u_tag {
    int ival;
    float fval;
    char *sval;
    } u;

    The variable u will be large enough to hold the largest of the three types; the specific size is implementation-dependent. Any of these types may be assigned to u and then used in expressions, so long as the usage is consistent: the type retrieved must be the type most recently stored. It is the programmer's responsibility to keep track of which type is currently stored in a union; the results are implementation-dependent if something is stored as one type and extracted as another.

    Syntactically, members of a union are accessed as

    union-name.member

    or

    union-pointer->member

    just as for structures. If the variable utype is used to keep track of the current type stored in u, then one might see code such as

    if (utype == INT)
    printf("%d\n", u.ival);
    if (utype == FLOAT)
    printf("%f\n", u.fval);
    if (utype == STRING)
    printf("%s\n", u.sval);
    else
    printf("bad type %d in utype\n", utype);

    Unions may occur within structures and arrays, and vice versa. The notation for accessing a member of a union in a structure (or vice versa) is identical to that for nested structures. For example, in the structure array defined by

    struct {
    char *name;
    int flags;
    int utype;
    union {
    int ival;
    float fval;
    char *sval;
    } u;
    } symtab[NSYM];

    the member ival is referred to as

    symtab[i].u.ival

    and the first character of the string sval by either of

    *symtab[i].u.sval

    symtab[i].u.sval[0]

    In effect, a union is a structure in which all members have offset zero from the base, the structure is big enough to hold the ``widest'' member, and the alignment is appropriate for all of the types in the union. The same operations are permitted on unions as on structures: assignment to or copying as a unit, taking the address, and accessing a member.

    A union may only be initialized with a value of the type of its first member; thus union u described above can only be initialized with an integer value.

    The storage allocator shows how a union can be used to force a variable to be aligned on a particular kind of storage boundary.

    ReplyDelete