[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1485
  • Last Modified:

struct within a union

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
arut
Asked:
arut
  • 3
  • 2
  • 2
  • +5
1 Solution
 
AlexFMCommented:
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
 
rajeev_devinCommented:
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
 
LinzerCommented:
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
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
cupCommented:
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
 
KocilCommented:
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
 
akshayxxCommented:
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
 
rajeev_devinCommented:
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
 
akshayxxCommented:
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
 
akshayxxCommented:
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
 
manirupCommented:
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
 
manirupCommented:
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
 
LinzerCommented:
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
 
arutAuthor Commented:
Kocil,

Thanks a lot for the excellent explanation!

Regards,
Arut
0

Featured Post

Prepare for an Exciting Career in Cybersecurity

Help prevent cyber-threats and provide solutions to safeguard our global digital economy. Earn your MS in Cybersecurity. WGU’s MSCSIA degree program curriculum features two internationally recognized certifications from the EC-Council at no additional time or cost.

  • 3
  • 2
  • 2
  • +5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now