【问题标题】:How to check the size of struct w/o padding?如何检查没有填充的结构的大小?
【发布时间】:2013-01-01 02:47:06
【问题描述】:

假设我有一个结构:

struct A {
  uint16_t a;
  uint64_t b;
};

有没有办法获得 A w/o padding 的大小?即:所有成员的sizeof之和(即使它不是递归的)。

通常sizeof(A) == 16. 我想要__GCC_sizeof__(A) == 10

我希望它在不影响实际代码的测试代码中使用,这意味着结构定义中没有"#pragma"s 和"__attribute__"。 (虽然用#ifdef TEST可以做到,但是很丑)。

不一定非要便携,GCC 就够了。

谢谢!

【问题讨论】:

  • 我怀疑它可以在没有编译指示的情况下完成。
  • 澄清一下,你是想从你的结构中删除填充,还是只是得到它将是没有填充的大小?
  • 斯拉夫语,第二部分。只是干净的大小(留下填充)。
  • 没有意义 TBH。例如。您期望 __GCC_sizeof__(&A::a) 的价值是多少?指向成员的指针中可能有一些填充,但您不能对此采取行动。
  • 嗯,指针的大小不是针对特定架构固定的吗?我可能希望它在我使用的系统上是 8 个字节。

标签: c++ c gcc


【解决方案1】:

我认为sizeof(A::a) + sizeof(A::b) 应该为您解决问题。没有办法获得未填充的结构大小,因为这样的大小可以为程序服务什么目的?

【讨论】:

  • 更一般地说,GCC 或任何其他编译器是否允许您单独反映结构的成员?
  • 目的是能够从测试内部跟踪新添加的结构成员。这意味着如果有人将新成员添加到结构中,我的测试将确保该成员在测试中被寻址,例如新成员是否通过某个网络正确发送?如果我采用常规 sizeof 那么这个成员可以填充一个填充而不影响 sizeof 的结果。
  • 为什么不只需要一个 operator== 来为该结构做任何正确的事情,而不是试图猜测您的测试中哪些语义是正确的?
  • @MarkB:如果您需要使用结构的 sizeof 从文件中读取确切的字节数,那么您需要不带填充的确切大小。
【解决方案2】:

目的是能够从测试内部跟踪新添加的结构成员。

如果你先问这个会更好......

答案是肯定的,有办法,但不是通过#include文件;您应该使用能够获取 AST/ABT 结构并列出字段然后将其与预先注册的列表进行比较的东西。例如,使用 Clang 可以做到这一点。


但是现在,让我们更进一步。你为什么要测试它?很脆!

最好测试一下功能,隐藏的东西是有原因的。

如果每个功能都经过正确测试,那么只要测试通过,您是否知道字段列表并不重要。

【讨论】:

  • 总的来说,我同意最好测试接口。在这种情况下,测试适用于执行某种 IPC 的模块,当您向其中添加结构时,您必须明确说明每个成员字段(是的,它是一个非常蹩脚的框架),所以我想确保如果结构增长,则更新模块。我从这次讨论中得出的结论是,不存在这种神奇的 sizeof。我会尝试不同的方法。谢谢
【解决方案3】:

我会看看这个 Stackoverflow 响应:

Is gcc's __attribute__((packed)) / #pragma pack unsafe?

并在此网站上获取 GCC 信息:

http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html

如果您将结构之前的 pragma 设置为 1,它应该在字节边界上对齐并且是紧凑的大小,因此您可以使用 sizeof 来获取字节数。

如果只是少量的结构体,可以在结构体声明前启用pragma,之后再禁用。

希望 about 对您的工作有所帮助。

【讨论】:

  • 他明确表示不想使用编译指示或属性。
  • 再次,我不想影响“生产”代码,只是测试。正如我所说,也许将 pragma 或属性放在#idefs 中是一种方式,但这是一种非常丑陋的方式。
【解决方案4】:

在 C 语言中,您可以使用预处理器指令 #pragma 来检查 sizeof 结构而无需填充..

#pragma pack(1)  

会给你sizeof 没有填充的结构..

【讨论】:

  • 这个pragma必须在结构声明之前,我不想影响实际代码。
  • #pragma pack 是非标准的。
猜你喜欢
  • 2016-09-18
  • 2020-07-26
  • 1970-01-01
  • 2018-02-11
  • 2012-08-22
  • 2018-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多