获取联合内匿名结构的大小

问题描述 投票:0回答:4

我希望这不是一个重复的问题,但我已经进行了一些详细搜索,但之前没有找到我的确切案例。

我有一个简单的结构,我也希望能够将其作为简单的字节数组进行访问

union
{
  struct
  {
    unsigned char a;
    unsigned char b;
    // ... Some other members ...
    unsigned char w;
  };
  unsigned char bytes[sizeof( what? )];
} myUnion;

请注意,该结构体没有命名,也没有给出自己的成员名称。这样我就可以使用

myUnion.a
来访问该成员,而不是
myUnion.myStruct.a

但是,如果没有一些名称,除了每次更改某些内容时手动计算它之外,如何获取

myUnion.bytes[]
的结构大小?

我当前的解决方法是使用

#define
来弥补
myUnion.myStruct
问题,但这会带来负面影响,即破坏编辑器中的自动完成功能,并且还会使我的数据结构更难以理解。

有什么想法吗?

注意: 这是在 8 位处理器上运行。不存在单词对齐等问题。也就是说,任何警告都应该说明,以便其他人不会不恰当地使用建议的解决方案。

c++ c struct sizeof unions
4个回答
7
投票

干脆摆脱工会吧。您可以通过将其地址转换为

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
投票

这会起作用:

union
{
  struct
  {
    unsigned char a;
    unsigned char b;
    // ... Some other members ...
    unsigned char w;
  };
  unsigned char bytes[1];
} myUnion;

0
投票

你无法回避命名以前的匿名结构。


0
投票

您可以使用宏来保留匿名结构:

#define ANON struct { unsigned char a; unsigned char b; }
#define ANON_SIZE sizeof(ANON)

union {
    ANON;
    unsigned char bytes[ANON_SIZE];
} myunion;
© www.soinside.com 2019 - 2024. All rights reserved.