Originally Posted by mjones490
The maximum size size of var is size_of(type_t) + size_of(int).
It can easily be larger than that.
could easily be larger than int
Second, type_t might be an odd size and the architecture might have an alignment requirement for either char*
So, the idea is valid (the union has enough space for just the largest of its members, not the sum of the sizes of its members). But the way you expressed it was not correct.
Originally Posted by MTK358
What are they practically useful for
That is a harder question.
There are situations where you want some polymorphic structure and you want to minimize the wasted space of the elements that don't apply to the current "shape" of the structure. In C++, that is usually better accomplished by multiple structures inheriting from a common base class. But in C, you don't have inheritance, so a workable alternative is a struct consisting of an union, plus an enum (or similar) to tell which member of the union is valid.
There are also cases in both C and C++, where you want the conceptual equivalent of a C++ reinterpret_cast. Reinterpret a pointer or reference to one type as a pointer or reference to another type in order to cause the referenced bit pattern to be read and reinterpreted (not translated) as a different type from the one that was written there. As I understand the aliasing rules of C++, a reinterpret_cast used in that way will under many conditions be broken by the optimizer. So even in C++, you may need a union to do what you'd like a reinterpret_cast to do. In C, a simple cast (all you have) of a pointer does have the semantics of a C++ reinterpret_cast, but a union is probably the safer way to accomplish a reinterpret of a bit pattern as a different type.
Any reinterpret of a bit pattern as a different type is inherently non portable (unlike the other use of union I described first). But sometimes it is the only effective tool for the job.