In short, I just wanted to make sure that use of union is not harmful for embedded systems in this case.
It depends in what way you intend to use the members.
What you are really doing by defining data as one type and aliasing it as another is type-punning.
As GCC supports its use ( mostly ) you can use it here in Arduino land, however:
* The C99 and C11 standards allow it.
* The C++99 and C++11 standards do not.
As you are using a char type as the second member things are different. C++ explicitly allows type-punning to a char type, whereas the other way around is undefined behaviour.
So if you write to the struct member, then read/write the array member its fine. But writing the array, then reading the struct can break strict-aliasing rules.
This makes your union usage more or less implementation defined, and therefore cannot really be considered portable: Even through future revisions. GCC currently says this:
*A member of a union object is accessed using a member of a different type.
The relevant bytes of the representation of the object are treated as an object of the type used for the access. See Type-punning. This may be a trap representation.
What this means is you can use your union fine as you have it laid out there, but consider this example:
union a{
uint16_t b;
uint32_t c;
char d[ 4 ];
};
a A = { 0xFFFF };
Initialising the smaller type of a union with unequal sized members means you can only safely access d upto d[sizeof(b)-1], and c cannot be touched at all.
Whereas if c or d is the active member, reading the others is fine.
The active member is the last written to member:
In a union, at most one of the non-static data members can be active at any time, that is, the value of at
most one of the non-static data members can be stored in a union at any time.