如何检查不考虑填充情况下结构体的大小?

8

Lets assume I have a structure:

struct A {
  uint16_t a;
  uint64_t b;
};

有没有一种方法可以获取A的大小,但不包括填充?即:所有成员的sizeof之和(即使它不是递归的)。
通常情况下,sizeof(A) == 16。我想要__GCC_sizeof__(A) == 10
我希望在测试代码中实现它,而不影响实际代码,这意味着结构定义中不需要"#pragma""__attribute__"。(虽然可以使用#ifdef TEST来完成,但非常丑陋)。
它不必具有可移植性,GCC就足够了。
谢谢!

我认为没有使用编译指示符是不可能完成的。 - Luchian Grigore
3
请问,您是想从结构体中移除填充(padding),还是只是想获取没有填充的结构体大小? - Matt Kline
斯拉维克,第二部分。只需干净的尺寸(不要留下填充)。 - Vadim S.
说实话这没什么意义。例如,你期望__GCC_sizeof__(&A::a)的值是多少?指向成员的指针可能会有一些填充,但你不能对其进行操作。 - MSalters
嗯,指针的大小不是针对特定架构固定的吗?我可能会期望在我使用的系统上它的大小为8个字节。 - Vadim S.
4个回答

4

我认为sizeof(A::a) + sizeof(A::b)可以帮助你解决问题。无法获得结构体的未填充大小,因为这样的大小对程序有什么用处呢?


1
更通用地说,GCC或其他编译器是否允许您单独反映结构体的成员? - Aniket Inge
1
目的是能够从测试内部跟踪新添加的结构成员。这意味着,如果有人向结构中添加了一个新成员,我的测试将确保该成员在测试中得到处理,例如,新成员是否正确地通过某个网络发送? 如果我使用常规的sizeof,则该成员可以填充填充区域,不会影响sizeof的结果。 - Vadim S.
为什么不直接要求一个operator==,让它执行该结构体的正确操作,而不是试图猜测在测试中哪些语义是正确的呢? - Useless
1
@MarkB:如果你需要使用结构体的大小来读取文件中精确的字节数,那么你需要去除填充后的精确大小。 - user18490

3
目的是能够从测试内部跟踪新添加的结构成员。
最好先问这个问题...
答案是肯定的,但不是通过#include文件;您应该使用能够获取AST / ABT结构并列出字段然后将其与预注册列表进行比较的东西。例如,这是Clang可能的东西。
但现在,让我们更进一步。为什么要测试这个?它很脆弱!
最好测试功能,隐藏的东西有它的原因。
如果每个功能都被正确测试,则只要测试通过,则不必知道字段列表。

一般来说,我同意测试接口更好。在这种情况下,测试是针对执行某种IPC的模块而设计的,当您向其添加结构时,必须明确声明每个成员字段(是的,这是一个非常糟糕的框架),因此我希望确保如果结构增长,则更新模块。从这次讨论中我的结论是没有这样一种神奇的sizeof。我将尝试不同的方法。谢谢。 - Vadim S.

2

1
他明确表示不想使用编译指示或属性。 - netcoder
再次强调,我不想影响“生产”代码,只是测试代码。 就像我说的那样,也许在 #idefs 中放置 pragma 或 attribute 是一种方式,但这是非常丑陋的方式。 - Vadim S.

0
在C语言中,你可以使用预处理指令#pragma来检查没有填充的结构体的sizeof大小。
#pragma pack(1)  

将会给你不带填充的sizeof结构。


这个编译指令必须在结构声明之前,我不想影响实际的代码。 - Vadim S.
1
#pragma pack 是非标准的。 - Keith Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接