1. You've used the tag C++ for this question, yet you are using outdated C-Syntax.
union
is an unsafe construct from the C language that is only still available in C++ for compatibility reasons. C++ provides safe alternate means to implement anything that you would otherwise use a union for, such as class hierarchies, and inheritance.
2. There is a reason for rule 1. above: unions are unsafe. After your own experience you should recognize why. You and you alone are responsible for correctly accessing your union - neither the compiler nor the runtime can do that for you! If at one point you enter values into s1, then any accesses to s2 become invalid!
It is your responsibility to ensure that you always acces the correct struct - the one that was last initialized.
3. As Richard already pointed out, it isn't exactly helpful to use unnamed structs. This is yet another remnant of C Syntax that should best be forgotten! See Solution 2.
4. While I've pointed out in 1. that you shouldn't be using
union
in the first place, if you choose to ignore that advice, at the very least add one attribute to your struct S that indicates the struct that is currently being used. E. g. something like this:
struct S {
int utype;
union {
struct {
bool b;
float f1;
} s1;
struct {
float f2;
int i;
bool b;
} s2;
}
}
int main() {
S my_s;
my_s.utype = 1; my_s.s1.b = true;
my_s.s1.f1 = 3.14;
bool my_b;
float my_f;
if (my_s.utype == 1) {
my_b = my_s.s1.b;
my_f = my_s.s1.f1;
}
else {
my_b = my_s.s2.b;
my_f = my_s.s2.f2;
}
}
While this is much safer than your previous code, it's still awkward that you always have to specifically point out or inquire what part of the union you are using. Using classes and inheritance with a few get and set functions would be a lot easier.