So why is there a need to declare union and its child variables, why can not I use 1 simple variable by allocating the biggest memory as union biggest variable?
You could do that, but a union makes it much easier.
Your particular example does not make much sense, mostly because you have two of the same type, but also because all are integers. So let's take an example from the post you linked:
union {
int i;
float f;
} u;
This means that you can use u.i
when you want to treat the memory as int
or u.f
if you want to treat it like a floatfloat
.
So let's say you want to solve this without a union and just declare a variable "big enough". Which type do you pick? int
is at least 16 bit, and float
is at least 32 bit. So we pick a float
then? Nope, because it might be the case that on the target system, an int
is 64 bit and a float
32. So let's overdo things and pick the largest type that exists? Well, you could, but that kind of defeats the purpose of saving memory.
And how do we access them as different types if declared as variables? Consider this code:
float x;
int y = *(int*) x;
Should work nice, right? Nope, apart from the problem that sizes may vary, you will also run into problems with representations. There are a number of different ways of representing both integers and floats. You may also encounter problems with endianess.
You can mimic the behavior of unions without actually using them, but it will require A LOT of extra work. The resulting code is very likely to contain a lot of bugs, and is probably much slower and less portable too.
One use case is to achieve polymorphism. Here is a very simple example, and tbh, it does not look it make things much easier, but that's commonly the case with examples. Suppose we have this:
void print_float(float f)
{
printf("Value: %f\n", f);
}
void print_int(int i)
{
printf("Value: %d\n", i);
}
That could be replaced by this:
struct multitype {
union {
int i;
float f;
} data;
enum { INT, FLOAT } type;
};
void print(struct multitype x)
{
switch(x.type) {
case INT: printf("Value: %d\n", x.data.i); break;
case FLOAT: printf("Value: %f\n", x.data.f); break;
}
}