【发布时间】:2017-10-05 06:40:49
【问题描述】:
给定一个union类型的数组,如果满足以下条件:
- 数组中每个
union的活动成员都是一样的, -
sizeofunion中的每个成员都是一样的,并且 -
alignofunion中的每个成员都是一样的 - (可能)联合满足
StandardLayoutType的要求
那么以下操作是否安全:
- 将此数组转换为活动类型的指针(目的是将其作为活动类型的数组寻址)
- 解决上述数组的第一个元素以外的任何内容?
- 假设 1 和 2 是可能的;这适用于非标准布局类型吗?
例如,考虑以下代码段:
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++ 标准对这种情况的明确规定很感兴趣。我知道StandardLayoutTypes 可以安全地转换为结构的第一个成员或联合的活动元素,所以我怀疑我的第一个转换是安全的;但我不确定这是否适用于数组,并将其视为活动类型的数组。
我尝试在 SO 和 C++ 标准(N4660 C++17 草案)上进行一些搜索——但我没有任何运气
注意:由于编译器具有 C 兼容性,这个问题不是关于这是否会在实践中工作;这是一个严格的问题,它是否调用 C++ 中的 UB,以及它是否违反严格的别名规则。
【问题讨论】:
标签: c++ arrays pointers unions