这个 std::array 的并集的公共初始序列有问题吗?
Is there a problem with common initial sequence with this union of std::array's?
是否对 Guillaume Racicot 的评论 . Is there a problem with common initial sequence 感到困惑?至少对于 GCC 10.1 x86-64 (-O3 --std=c++20 -pedantic -Wall -Werror
) 我写 .words
并阅读 .bytes
.
sizeof(MyUnion)==32
也很安心
union MyUnion {
static constexpr std::size_t size = 32;
using byte = std::uint8_t;
using word = std::uint32_t;
std::array<byte, size> bytes;
std::array<word, size / sizeof(word)> words;
};
static_assert(sizeof(MyUnion)==32);
标准说:
[array.overview]
... An array is a contiguous container. ...
An array is an aggregate that can be list-initialized with up to N elements whose types are convertible to T.
array<T, N>
is a structural type if T is a structural type.
标准没有明确说明成员 std::array
有什么。因此,我们在技术上不能假设它具有任何类型的公共初始序列。
根据显示的对 std::array
的要求,我们可以合理地假设它具有 T[N]
类型的成员。如果这个假设是正确的,让我们来探讨一下是否存在一个共同的初始序列。
[class.mem.general]
The common initial sequence of two standard-layout struct ([class.prop]) types is the longest sequence of non-static data members and bit-fields in declaration order, starting with the first such entity in each of the structs, such that corresponding entities have layout-compatible types, ...
[basic.types.general]
Two types cv1 T1 and cv2 T2 are layout-compatible types if T1 and T2 are the same type, layout-compatible enumerations, or layout-compatible standard-layout class types.
std::uint8_t[32]
和 std::uint32_t[8]
不是同一类型(忽略 cv 限定符),它们也不是枚举,也不是 类。因此它们不是布局兼容的类型,因此它们不能属于同一公共初始序列。
结论:不,我们是否可以安全地假设std::array
的成员,没有共同的初始序列。
I write .words and read .bytes
程序的行为未定义。
鉴于您想将其作为(无符号)字符数组读取,重新解释而不是联合双关语是安全的:
static constexpr std::size_t size = 32;
using word = std::uint32_t;
std::array<word, size / sizeof(word)> words {
1, 2, 3, 4,
};
std::uint8_t* bytes = reinterpret_cast<std::uint8_t*>(words.data());
而且,如果你想要一个范围:
std::span<std::uint8_t, size> bytes_range {
bytes, bytes + size,
};
是否对 Guillaume Racicot 的评论 -O3 --std=c++20 -pedantic -Wall -Werror
) 我写 .words
并阅读 .bytes
.
sizeof(MyUnion)==32
也很安心
union MyUnion {
static constexpr std::size_t size = 32;
using byte = std::uint8_t;
using word = std::uint32_t;
std::array<byte, size> bytes;
std::array<word, size / sizeof(word)> words;
};
static_assert(sizeof(MyUnion)==32);
标准说:
[array.overview]
... An array is a contiguous container. ...
An array is an aggregate that can be list-initialized with up to N elements whose types are convertible to T.
array<T, N>
is a structural type if T is a structural type.
标准没有明确说明成员 std::array
有什么。因此,我们在技术上不能假设它具有任何类型的公共初始序列。
根据显示的对 std::array
的要求,我们可以合理地假设它具有 T[N]
类型的成员。如果这个假设是正确的,让我们来探讨一下是否存在一个共同的初始序列。
[class.mem.general]
The common initial sequence of two standard-layout struct ([class.prop]) types is the longest sequence of non-static data members and bit-fields in declaration order, starting with the first such entity in each of the structs, such that corresponding entities have layout-compatible types, ...
[basic.types.general]
Two types cv1 T1 and cv2 T2 are layout-compatible types if T1 and T2 are the same type, layout-compatible enumerations, or layout-compatible standard-layout class types.
std::uint8_t[32]
和 std::uint32_t[8]
不是同一类型(忽略 cv 限定符),它们也不是枚举,也不是 类。因此它们不是布局兼容的类型,因此它们不能属于同一公共初始序列。
结论:不,我们是否可以安全地假设std::array
的成员,没有共同的初始序列。
I write .words and read .bytes
程序的行为未定义。
鉴于您想将其作为(无符号)字符数组读取,重新解释而不是联合双关语是安全的:
static constexpr std::size_t size = 32;
using word = std::uint32_t;
std::array<word, size / sizeof(word)> words {
1, 2, 3, 4,
};
std::uint8_t* bytes = reinterpret_cast<std::uint8_t*>(words.data());
而且,如果你想要一个范围:
std::span<std::uint8_t, size> bytes_range {
bytes, bytes + size,
};