You are right to be confused! I'm confused... Let's look at something simple first before moving on to the more complex example you have.
First union basics. A union just means that when you create a variable of the union type, the underlying components (in the example below i and f) are really overlapping in memory. It lets you sometimes treat that memory as an int and sometimes treat that memory as a float. This naturally can be nasty and you really have to know what you're doing.
union AUnion
{
int i;
float f;
}; // assumes an int is 32 bits
AUnion aUnion;
aUnion.i = 0;
printf("%f", aUnion.f);
In the above code, what will be print out? Well to understand the answer to that question you have to understand how ints and floats are represented in memory. Both take up 32 bits of memory. How that memory is interpreted however differs between the two types. When I set aUnion.i = 0, I am saying "write a 0'd integer to aUnion". A 0'd integer, it so happens, corresponds to setting all 32-bits to 0. Now when we go to print aUnion.f, we are saying "treat aUnion as if the bits are really a 32-bit float, and print it out! The computer then treats all those underlying bits as if they are really parts of a float instead of the int. The computer knows how to treat any random bunch of 32-bits as a float because it knows how a floating point number is formatted in binary.
Now to take on some of your more complex union code:
enum Enums { k1, k2, k3, k4 };
union MYUnion {
struct U{
char P;
}u;
struct U0 {
char state;
} u0;
struct U1 {
Enums e;
char c;
int v1;
} u1;
All these structs are overlapped in the same way the int and float were above. Now if we assume that Enums are mapped to an int. Then we can map the enums to int values in the underlying memory, based on the rules of enums:
enum Enums { k1/*0*/, k2/*1*/, k3/*2*/, k4/*3*/ };
So then what we have is
union MYUnion {
struct U{
char P;
}u;
struct U0 {
char state;
} u0;
struct U1 {
int e;
char c;
int v1;
} u1;
And you have a very strange union because if you do
MyUnion m;
m.u.P = 'h'
When later you access the enum (which is most likely an int beneath the hoods), it will be read as an invalid value. This is because P is just 1 byte, and the int is 4 bytes. When read as the enum, you will get weird results.
I highly suggest you go sack who is responsible for this code.