C++ 在C+中引用工会成员有多安全+;?

C++ 在C+中引用工会成员有多安全+;?,c++,C++,想象一下这种情况: union Reg16 { uint16_t word; struct { uint8_t bottom; uint8_t top; }; }; 比如说,我在某个地方有这样的东西,使用了这个联合体: Reg16 reg_AF; uint8_t& reg_A = reg_AF.top; uint8_t& reg_F = reg_AF.bottom; 即使从技术上讲,活接头并不总是指u8,但保留

想象一下这种情况:

union Reg16
{
    uint16_t word;

    struct
    {
        uint8_t bottom;
        uint8_t top;
    };
};
比如说,我在某个地方有这样的东西,使用了这个联合体:

Reg16 reg_AF;
uint8_t& reg_A = reg_AF.top;
uint8_t& reg_F = reg_AF.bottom;
即使从技术上讲,活接头并不总是指u8,但保留对活接头各部分的引用是否安全?我不确定这是否违反了严格的别名规则,但值得注意的是,任何地方都没有提到
单词
,只有
顶部
底部
。特别是在这个特殊的情况下,引用应该指向整个u16的上半部分和下半部分,所以没有任何UB,因为我不会得到任何我不希望通过读取它们得到的值,而不是如果我有一个浮点和一个整型的并集并对它们进行引用


提前感谢。

首先要说的是,严格的别名规则(C++03标准第3.10节)中有明确的语言†允许通过
无符号字符
访问值。如果
uint8\u t
unsigned char
的类型定义,则此用法将明确合法

但是,
uint8\u t
可以是非
无符号字符
的实现定义类型的typedef(尽管仔细阅读该标准表明,如果存在
uint8\u t
,则其大小必须与
无符号字符
相同)。此外,这个问题对于其他类型(例如
uint32\u t
uint16\u t
)仍然有意义

现有的引用绝对没有危害-如果在联合体包含
单词
而不是
顶部
+
底部
时使用引用,则唯一的危险可能会出现。另一方面,如果发生这种情况(并且
顶部
/
底部
不是
无符号字符
),则违反了严格的别名规则

<> P>如果C标准明确允许通过联合进行类型双关(与C++不同),C++编译器也会允许这样做。 旁白:严格来说,样品是不合法的;匿名结构是GCC、Clang和MSVC支持的扩展(问题是,哪些编译器不支持匿名结构)


†在以后的版本中,措辞略有变化,章节编号可能有所变化,但原则保持不变。

假设您的代码实际上是:

union Reg16
{
    uint16_t word;

    struct
    {
        uint8_t bottom;
        uint8_t top;
    } bytes;
};
这是一个完美的宣言:

可以像直接使用结构成员一样使用引用


例如
reg_AF.bytes.bottom='A';STD::CUT代码不是有效的C++。C++中没有“未命名的结构”成员,引用相当完美。但是:如果你把垃圾放在工会里,从那里拿走价值观,你就会从中得到垃圾。我理解你的问题,你问了一些关于变量内容的实时性的问题。无论如何,这与工会无关。听起来您的代码中有一个更深层次的设计缺陷。@KerrekSB它作为GCC/Clang扩展是有效的,因此代码可以很好地编译。
Reg16 reg_AF;
uint8_t& reg_A = reg_AF.bytes.top;
uint8_t& reg_F = reg_AF.bytes.bottom;