我希望这不是一个重复的问题,但我已经搜索了一些细节,并且之前没有找到我的确切案例。
我有一个简单的结构,我也希望能够以简单的字节数组
进行访问union
{
struct
{
unsigned char a;
unsigned char b;
// ... Some other members ...
unsigned char w;
};
unsigned char bytes[sizeof( what? )];
} myUnion;
请注意,struct未命名,也没有自己的成员名称。这样我就可以使用myUnion.a
来访问该成员,而不是myUnion.myStruct.a
。
但是,如果没有一些名称,我怎样才能获得myUnion.bytes[]
结构的大小,而不是每次更改内容时手动计算它?
我目前的解决方法是使用#define
来弥补myUnion.myStruct
问题,但这会产生在编辑器中破坏我的自动完成的负面影响,同时也会产生我的数据结构难以理解。
有什么想法吗?
注意:这是在8位处理器上运行的。字对齐等问题没有问题。也就是说,任何警告都应该说明,以免其他人不适当地使用建议的解决方案。
答案 0 :(得分:6)
摆脱工会。您可以通过将其地址转换为char*
来安全地访问任何可复制的结构作为字节数组,并且当您从非活动的联合成员读取时,转换将不会与未定义的行为相冲突。
struct
{
unsigned char a;
unsigned char b;
// ... Some other members ...
unsigned char w;
// array-style access
unsigned char& operator[](size_t i)
{ return reinterpret_cast<unsigned char*>(this)[i]; }
} myStruct;
以这种方式进行转换是安全的原因是char
是严格别名限制的特殊例外。
对于工会,您获得的唯一特殊权限是访问“共享一个共同初始序列的标准布局结构”的成员......并且遗憾的是,数组不符合“标准布局结构”的条件”。我希望看到规则更改为“标准布局结构或聚合”,但在当前的措辞中,联合版本并不安全。
在C99中,但不是任何版本的C ++,您可以使用灵活的数组成员,而不需要指定大小。
union
{
struct
{
unsigned char a;
unsigned char b;
// ... Some other members ...
unsigned char w;
};
unsigned char bytes[];
} myUnion;
击> <击> 撞击>
答案 1 :(得分:1)
这将有效:
union
{
struct
{
unsigned char a;
unsigned char b;
// ... Some other members ...
unsigned char w;
};
unsigned char bytes[1];
} myUnion;
答案 2 :(得分:0)
你无法命名以前的匿名结构。