C++ 我有一个数组的并集。可以从一个数组中读取一些元素,从另一个数组中读取其他元素吗?

C++ 我有一个数组的并集。可以从一个数组中读取一些元素,从另一个数组中读取其他元素吗?,c++,c,C++,C,我有以下工会: union PM_word { uint8_t u8[8]; uint16_t u16[4]; uint32_t u32[2]; uint64_t u64[1]; }; 假设我初始化此联合的一个实例,如下所示: PM_word word; word.u32[0] = 0; word.u16[2] = 1; word.u8[6] = 2; word.u8[7] = 3; 如果我理解正确,尝试读取word.u32[1]是未定义的行为,因为已设置的

我有以下工会:

union PM_word {
    uint8_t  u8[8];
    uint16_t u16[4];
    uint32_t u32[2];
    uint64_t u64[1];
};
假设我初始化此联合的一个实例,如下所示:

PM_word word;
word.u32[0] = 0;
word.u16[2] = 1;
word.u8[6] = 2;
word.u8[7] = 3;
如果我理解正确,尝试读取
word.u32[1]
是未定义的行为,因为已设置的
word.u16
word.u8
的元素与其重叠。但是,读取
word.u32[0]
也是未定义的行为吗


<强>编辑: C++。如果C和C++的语义在这方面有不同,那么C和C++的答案都是非常值得赞赏的。

< P>我会说,行为不是没有定义的,只是你所期望的不是… 正如您所指出的,由于内存溢出,您不能同时使用(set)。 但例如,同时使用
word.u8[0]
word.u8[1]
word.u16[1]
就可以了。
只要您使用
word.u64[0]
所有其他变量都将更改。如果它们被破坏,则取决于值…

< p>相关C++标准引号:

[班级工会]

在联合中,如果非静态数据成员的名称引用的对象的生存期已开始但尚未结束([basic.life]),则该成员处于活动状态。联合类型的对象的最多一个非静态数据成员在任何时候都可以处于活动状态,也就是说,最多一个非静态数据成员的值在任何时候都可以存储在联合中。[…关于具有公共初始序列的类的特殊情况,不适用于本例,因为联合没有类类型的成员…]

当赋值运算符的左操作数涉及指定联合成员的成员访问表达式([expr.ref])时,它可能会开始该联合成员的生存期,如下所述。 对于表达式E,定义E的子表达式集S(E),如下所示:

  • 如果E的形式为A[B],并被解释为内置数组下标运算符,则S(E)在A为数组类型时为S(A),在B为数组类型时为S(B),否则为空

  • […其他案例不相关,因为引用的案例适用于…]

在使用内置赋值运算符([expr.ass])或普通赋值运算符([class.copy.assign])的形式为E1=E2的赋值表达式中,对于S(E1)的每个元素X,如果X的修改在[basic.life]下具有未定义的行为,则在指定存储中隐式创建X类型的对象;不执行初始化,并且在左操作数和右操作数的值计算之后和赋值之前对其生存期的开始进行排序。 [ 注意:这将结束联合的先前活动成员的生存期(如果有)([basic.life])。 — 尾注  ]

这意味着在语句
word.u8[6]=2;
之后,只有
word.u8
成员处于活动状态,所有其他联合成员处于非活动状态。在最后一个语句
word.u8[7]=3;
之后,只有
word.u8[6]
word.u8[7]
具有初始化值

非活动成员的生存期已结束。以下是有关读取其值是否正确的相关规则:

[基本生活]

类似地,在对象的生存期开始之前,但在对象将占用的存储被分配之后,或者在对象的生存期结束之后,在对象占用的存储被重用或释放之前,可以使用引用原始对象的任何glvalue,但只能以有限的方式使用作为未定义的行为,如果:

  • glvalue用于访问对象,或

因此,是的。访问非活动成员将是UB(除非该访问是一个赋值,或者根据[class.union],在特殊情况下涉及公共初始类序列).

如果您没有明确设置该值,它的值将是未定义的。由于内存重叠,更改u16或u8意味着读取u32是未定义的。在实践中,您仍然可以读取u32,这可能会有一些意义,具体取决于您设置的u16和u8值。这实际上取决于平台。不同的计算机将安排不同的是,你从U32读取的实际值将根据具体的计算机而不同,只要我在C++中理解,你就不能这样做。你必须把代码> MeMCPY < /CUD>一个数组,你想访问它的任何数组,以便它被定义为C++中的行为。C++不做类型的惩罚。C和C++。在这个问题上,你不应该在一个问题上同时指出这两个问题。