Given an array of some union type, if the following conditions are met:
- the active member of each
unionin the array is the same, sizeofeach member within theunionis the same, andalignofeach member within theunionis the same- (possibly) the union satisfies the requirements for
StandardLayoutType
then are the following actions safe:
- casting this array to a pointer of the active type (for the intent of addressing it as an array of the active type)
- addressing anything other than the first element of the above array?
- assuming 1 & 2 are possible; does this hold for non standard-layout-types?
For example, consider the following code-segment:
template<typename T, typename U>
union storage_type
{
T value0;
U value1;
};
static_assert( sizeof(int) == sizeof(float), "" );
static_assert( alignof(int) == alignof(float), "" );
storage_type<int,float> storage[] = { {1}, {2}, {3} };
// the active type of all storage_type is 'int', so cast to int*
// to be treated as an array of ints
auto* array = reinterpret_cast<int*>(&storage[0]);
assert( array[0] == 1 );
assert( array[1] == 2 );
assert( array[2] == 3 );
I'm interested in what the C++ Standard has to explicitly say about such a case. I know that StandardLayoutTypes are safe to cast to the first member of the structure or active element of the union, so I suspect that my first cast is safe; but I'm unsure if this would hold true for an array, and treating it like an array of the active type.
I tried doing some searching, both on SO and in the C++ standard (N4660 C++17 draft) -- but I didn't have any luck
Note: This question is not about whether this will work in practice due to compilers having C compatibility; this is strictly a question on whether this invokes UB in C++, and whether it violates strict-aliasing rules.