给定一些union
类型的数组,如果满足以下条件:
union
的活动成员都是相同的,sizeof
union
中的每个成员都是相同的,alignof
union
中的每个成员都是相同的StandardLayoutType
然后是安全的以下行动:
例如,请考虑以下代码段:
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 );
我对C ++标准明确说明这种情况感兴趣。我知道StandardLayoutType
可以安全地投射到结构的第一个成员或联盟的活跃元素,所以我怀疑我的第一个演员是安全的;但我不确定这是否适用于数组,并将其视为活动类型的数组。
我尝试在SO和C ++标准(N4660 C ++ 17草案)中进行一些搜索 - 但我没有运气
注意:由于编译器具有C兼容性,此问题与在实践中是否有效无关;这是否是在C ++中调用UB以及它是否违反严格别名规则的问题。
答案 0 :(得分:0)
理论上讲,这可能会失败。按照标准:
联合的大小足以包含其最大的数据成员。
因此,从理论上讲,sizeof(my_union)和sizeof(largest_member)可能会有所不同。
如果你static_assert()它是相同的,那么:
int* array = &storage[0].value0;
...由于数组索引的工作原理,它是否可以无UB。