【问题标题】:How does one determine the size of an unnamed struct?如何确定未命名结构的大小?
【发布时间】:2014-01-07 20:47:45
【问题描述】:

我正在寻找一种方法来确定未命名结构的大小,因为我想显式计算填充。

我有一组具有共同总体布局的结构

struct Packet {
  uint8_t AllocatorDebugInfo[ALLOC_SIZE /* constant across all structs */ ];
  /* OPTIONAL */ uint8_t Padding[       /* Needs to be determined */      ];
  uint8_t Header[HEADER_SIZE            /* dependent on  packet type */   ];
  uint8_t Payload[PAYLOAD_SIZE          /* constant across all structs*/  ];
}; 

我有以下要求:

  • 我编写了一个特殊用途的分配器,它在数据包前面有调试信息。
  • 我想要可交换的标头类型,同时保持所有数据包类型布局兼容的有效负载。

我正在尝试计算标题大小,如下面的代码所示:

typedef union {
  struct { /* opaque */ } SmallHeader;
  struct { /* opaque */ } MedHeader;
  struct { /* opaque */ } LargeHeader;
} HeaderSizes;

HeaderSizes *p;
enum { SMALL_PADDING = sizeof(HeaderSizes) - sizeof(p->SmallHeader)) };

不幸的是内存很紧,我正在寻找避免全局指针的方法。

编辑:

显然尝试像这样计算可选填充是一个非常糟糕的主意。这只有在您意识到最大的结构将具有比预期更多的填充(零)时才有效。

enum { LARGE_PADDING = sizeof (HeaderSizes) - sizeof ((HeaderSizes*)0->LargeHeader) };
struct LargePacket {
  uint8_t AllocDebug[ALLOC_SIZE];
  uint8_t Padding[ LARGE_PADDING ]; /* will evaluate to 0 -- struct size 1 */
  uint8_t Payload[ PAYLOAD_SIZE ];  /* off by 1 */
};

【问题讨论】:

    标签: c


    【解决方案1】:

    sizeof 运算符不需要有效的实例来返回大小。它只需要一个计算为正确类型的表达式。虽然这有点小技巧,但您可以将 NULL 转换为 HeaderSizes*

    sizeof(((HeaderSizes*)NULL)->SmallHeader)
    

    由于这不是取消对空指针的引用,而是一种语法结构,因此上述内容完全有效并给出了正确的结果。比如下面的例子。

    http://ideone.com/QKTOdP

    【讨论】:

    • 使用 NULL 而不是 0 会更好,但是:1+
    • @alk,谢谢。这些天我一直在做更多的 C++ :)
    • ideaone 中的代码示例是一个命名结构。我认为问题是关于计算未命名结构的sizeof?例如,这会失败:asciinema.org/a/nbsd9MQxMOOmM2e73l4SI1o2P 你看到有 20 个字节,但 sizeof 没有反映这一点。
    • @ifelsemonkey - ideone 中的代码示例通过引用字段的表达式计算字段的大小。它不计算容器的大小,因此它是一个命名结构这一事实没有影响
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-11
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 2021-04-08
    • 2013-12-12
    相关资源
    最近更新 更多