?
Solved

struct within a union

Posted on 2003-03-06
13
Medium Priority
?
1,442 Views
Last Modified: 2007-12-19
typedef union xyz__tag
{
     struct
        {
               int  id ;
               int  cntr;
     } str;
        int ul;
} xyz;

I would like to know what is the idea behind having a struct within a union as above.

Previoulsy I had come across a union within a struct, not the other way around.


Thanks,
Arut
0
Comment
Question by:arut
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +5
13 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 8079304
This union is not useful: str.id and ul are placed in the same place in memory.

struct in union may be used, foe example, by such way:

union U
{
    struct S
    {
        unsigned short nHighWord;
        unsigned short nLowWord;
    } str;

    unsigned int n;  // gets the same place in memory as str
};

U m_u;

m_u.n = <number>;

// now m_u.str.nHighWord contains high word of number
//     m_u.str.nLowWord contains low word of number
0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 8079474
The the thing that i can say is that, the use of struct within union, or union within struct, depends on the type of application you are trying to build. The concept is important.Let me give you one example:

union student
{
   struct record
   {
      BYTE red;
      BYTE green;
      BYTE blue;
   }rgb;
   BYTE gray_scale;
};

Say this structure is used to store the pixels of an image. If the image is gray-scale, then only gray_scale can be used, otherwise rgb can be used. Just watch the structure carefully. It will be clear.

Hope this example will clarify your confusion.
0
 
LVL 1

Expert Comment

by:Linzer
ID: 8079972
AlexFM, your code example looks quite dirty... Are you sure that C standards tell how compilers should store members of unions in memory?  And of course your code depends on the system's endianness. There are, IMO, better ways to cut a word into bytes! The only 'clean' way is, I think, using bit masking. If you WANT to go low-level, I'd prefer casting a (WORD *) to a (BYTE *), at least you explicitly access the same memory range.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 11

Expert Comment

by:cup
ID: 8082605
Basically, the user wants to hold data that is either an int or str where str contains an id and a counter.  The problem is, there is nothing to indicate which part of the union is in use.  At a guess, the id and ul are used in a special way.  It may be that if it is negative, then it is an id otherwise it is a ul.  If it is an id, there will be a counter associated with it.

A lot of this is to do with space saving.  Sometimes it has a negative effect in that the data actually ends up larger than expected.  I once worked on a project where they had

struct {
    int type;
    union {
        float f;
        int i;
        char c[CHAR_MAX];
    } u;
};

CHAR_MAX was initially 8.  Then it grew to 16, 32 and finally 128.  We were passing arrays of these between computers and the packet size just grew and grew.  The point is a lot of it was just wasted space and we were sending tons of unused data across the link.
0
 
LVL 5

Accepted Solution

by:
Kocil earned 400 total points
ID: 8084244
Basically, struct puts a field after another field (serially).
On the other hand, union puts all fields in the same location (paralelly).

So this (i modified ul = long int to make it clearer)
union {
  int id;
  int cntr;
  long int ul;
}
gives you memory layout (assume int = 2 bytes, long=4 bytes)
1234      (memory addr, total 4)
**        (id)
**        (cntr)
****      (ul)


And this
struct {
   int id; int cntr; int ul;
}
gives you memory layout
12345678  (memory addr, total 8)
**        (id)
--**      (cntr)
----****  (ul)


If you write struct inside a union
union {
  struct {int id; int cntr} str;
  long int ul;
}
You will get memory layout
1234      (memory addr, total 4)
**        (str.id)
--**      (str.cntr)
****      (ul)

Usually u use this construct to access a variable as a separates or one entity.
For example:

union xyz AAA;

// separated access
AAA.str.id = 0x10;
AAA.str.cntr = 0x40;

// this single access will give the same result
AAA.ul = 0x4010;


0
 
LVL 8

Expert Comment

by:akshayxx
ID: 8085298
refer to what CUP said ..and also others ( kocil Alex , linzer etc)
and as long as u understand what a UNION is and what a STRUCT is .. it really doesnt matter much if u put struct in union or union in struct ..
u shud  know what u r doing..

Also following is useless for many reasons ..
union student
{
  struct record
  {
     BYTE red;
     BYTE green;
     BYTE blue;
  }rgb;
  BYTE gray_scale;
};

0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 8085952
reply to akshayxx:

The asker wants to know tghe idea behind using a struct within an union. thats' why I gave him that example. I dont' think the example i gave is useless. may be i seems useless to you.
0
 
LVL 8

Expert Comment

by:akshayxx
ID: 8086145
union student
{
 struct record
 {
    BYTE red;
    BYTE green;
    BYTE blue;
 }rgb;
 BYTE gray_scale;
};

i should have explained in more detail
its useless for the following reasons..
1. he needs to define BYTE .. ofcourse it will be unsigned char
2. since rgb and gray_scale occupy same memory space
and sizes of 'rgb.red' and and gray_scale is same .. so its useless to have gray_scale.. may be redundant is better word
as it will 'always' have same value as 'rgb.red'...refer to the first comment from "AlexM"
3. even if u go about with above definition .. u need extra variable which shud tell you which value to read .. rgb OR gray_scale..  the variable can be global .. ( then it will apply to all the variables of type 'ur_union"
OR it can be put into rgb struct ( THAT 'TYPE' FLAG SHOULD NOT BE PUT INTO union' )
>> WRONG --> union u{ BYTE flag; struct { BYTE r,g,b;}rgb; BYTE gray;};
>> DO ABLE --> union u{struct { BYTE r,g,b;  BYTE flag; }rgb; BYTE gray;};

refer to "cup's" comment

4. if u wanted to give him example of how u can get gray_scale from corresponding R,G,B  by using union .. then also its wrong..
as ur gray_scale field will give only Red value ..
whereas to convert a RGB value to gray_scale value either u take "arithmetic mean" OR weighted average of RGB values..
but in your case you are just ignoring the G and B values..


and please dont take anything personal . i just wanted to say that the above mentioned struct will not be 'useful' in the context that u said.. so as the asker doesnt get misled
0
 
LVL 8

Expert Comment

by:akshayxx
ID: 8086170
as cup has already told ..
usually the way to do is .. encapsulate the  your union data-type into some struct ..with a flag that wud tell you which feild of the union shud be picked..
OR keep the flag global .. but u NEED to have such a flag..  for any practical use..

so even following, on its own, is useless
typedef union xyz__tag
{
    struct
       {
              int  id ;
              int  cntr;
    } str;
       int ul;
} xyz;

for the reasons that it needs a flag . and for the reason that .. int ul, and int str.id will ALWAYS have same values
0
 
LVL 1

Expert Comment

by:manirup
ID: 8086365
Arut,
i hope u know the difference between structure and union. Anyway, the size of a structure is the sum of the sizes of the data that are declared within the structure, while that of a union is the size of the largest data type declared in the union.For example,
struct xyz{
  char  a;
  int   b;
  float c;
};
assuming that int takes 2 bytes and float 4, the size of xyz is 7.
But if u declare
union xyz{
  char  a;
  int   b;
  float c;
}
then the size of xyz is 4.
Now, if u r using a union within a struct, it means that u know in advance that some of the properties of the structure may take either of the values that u r going to define within the union that is nested inside the structure. For example,
struct student{
  char *name;
  char *roll_no;
  union marks
  {
     int   total;
     float percentage;
     char  grade;
  };
  ...
  ...
  ...
}
In this example, the programmer is not sure of the details of the student. His marks may be available in either total aggregate, or may be in percentage, or may be available in grade like A,B,C,D etc.. If all these were part of the structure itself then the size of the structure would have increased by 3 bytes, whereas using union decreases the size of the structure, as only one of total, percentage, or grade is stored in a student entry.
Hope this helps u.

Bye
 Manirup
0
 
LVL 1

Expert Comment

by:manirup
ID: 8086371
Arut
oh sorry, I have misunderstood u'r question. I have given an illustration union within structure rather than structure within union. sorry.
Manirup
0
 
LVL 1

Expert Comment

by:Linzer
ID: 8087051
manirup :
---------------------
Anyway, the size of a structure is the sum of the sizes of the data that are declared within the structure.
For example,
struct xyz{
char  a;
int   b;
float c;
};
assuming that int takes 2 bytes and float 4, the size of xyz is 7.
--------------------

This isn't true. For alignment reasons, the size of your struct is likely to be at least 8. To minimize this size, you should store them in the following order :

struct xyz{
float c;
int   b;
char  a;
};      
0
 

Author Comment

by:arut
ID: 8093444
Kocil,

Thanks a lot for the excellent explanation!

Regards,
Arut
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question