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;