C 如何找到所有可以通过更改成员顺序来缩小的结构

C 如何找到所有可以通过更改成员顺序来缩小的结构,c,memory,embedded,struct,C,Memory,Embedded,Struct,背景:编译器可能会在结构中插入填充,以使其成员更好地对齐。这将导致结构的大小大于其成员大小之和。对结构的成员进行重新排序,以便更好地打包,这样可以消除编译器以这种方式填充的需要,并使结构更小,从而节省内存。我需要节省内存 回退选项是手动检查每个结构。我正在寻找一种可以减少工作量的自动化方法 即使它只是减少了手工检查的结构的数量,这也会有所帮助 因此,例如,一个进程/工具/etc列出了所有大于其成员大小之和的结构,虽然不完美,但仍然会有帮助,因为它会限制需要手动检查的结构 有没有人知道有什么工具可

背景:编译器可能会在结构中插入填充,以使其成员更好地对齐。这将导致结构的大小大于其成员大小之和。对结构的成员进行重新排序,以便更好地打包,这样可以消除编译器以这种方式填充的需要,并使结构更小,从而节省内存。我需要节省内存

回退选项是手动检查每个结构。我正在寻找一种可以减少工作量的自动化方法

即使它只是减少了手工检查的结构的数量,这也会有所帮助

因此,例如,一个进程/工具/etc列出了所有大于其成员大小之和的结构,虽然不完美,但仍然会有帮助,因为它会限制需要手动检查的结构

有没有人知道有什么工具可以做到这一点,或者有没有人可以建议一些可能有用的方法


p、 我需要在一个包含100多万行代码的嵌入式C代码库上执行此操作。

您可以编写一个程序,然后为结构中的每个字段排列编写一个小C程序,当编译输出程序并运行它时,打印出结构大小。如果字段的数量远远大于10个左右,这将变得不切实际。

是一个用OCaml编写的健壮的C解析器,能够理解结构的填充。它附带了一个检测C程序。结构填充是特定于平台的,我不怀疑您知道这一点,但您可以在您的问题中更清楚地说明这一点。与CIL一起打包的检测程序检测类型的大小,CIL假设用于填充结构的算法是,第n个字段的偏移量通过四舍五入(第(n-1)个字段的偏移量+第(n-1)个字段的大小)到(第n个字段的对齐)的最近倍数来计算


从CIL开始,制作所需工具的OCaml将少于200行。但可能还有更好的解决方案。

gcc的-Wpadded警告选项可用于告诉您何时填充结构。这不会告诉你什么时候结构可以变小,但它可以帮助减少工作量

是专门为此目的编写的实用程序。它将分析编译的对象文件(在启用调试的情况下编译),并向您显示结构漏洞。

这没有多大意义。通常,将字段从大到小排序会生成最佳填充。@如果某些类型大小不是2的幂,例如10字节扩展双精度,甚至
char t[5],则Anon会保持为真
?一个
字符数组应与其他
字符一起排序-如果说字段应按对齐要求排序,可能会更准确。@Anon我明白了。我认为重新表述的版本可以在数学上得到证明,假设(1)对齐是2的幂,并且(2)大小是对齐的倍数。我曾经遇到一个编译器,它的文档似乎与(2)相矛盾,但事实上编译器确实满足了它,文档是错误的。@Pascal:大小必须是对齐的倍数,否则数组中的第二个元素将不对齐。C具有标识
(char*)(p+1)==(char*)p+sizeof(*p)
。至少,这就是我认为标准中“连续分配”的意思——如果在p[0]的结尾和p[1]的开头之间有字节,那么它们就不是连续的。我觉得自己像个白痴,因为还没有找到这个选项。大多数编译器都有一个选项,可以将结构紧密打包——在MSVC++上,这是
/Zp
,在gcc上,它是
-fpack struct
。请注意:(1)这将破坏ABI与其他代码的兼容性;(2)大多数CPU处理未对齐数据访问的速度会更慢(或者在某些体系结构上根本不会)。我回来投票支持您,使用了一段时间后,我不得不说pahole非常棒