关于C#:为什么GCC不优化结构?

Why doesn't GCC optimize structs?

系统要求某些基元与内存中的某些点对齐(整数到4的倍数字节,短于2的倍数字节等)。当然,这些可以被优化以在填充中浪费最少的空间。

我的问题是为什么海湾合作委员会不自动这样做?在某种程度上是否缺少更明显的启发式(从最大的大小需求到最小的顺序变量)?某些代码是否依赖于其结构的物理顺序(这是个好主意)?

我只是在问,因为GCC在很多方面都是超级优化的,但在这个方面没有,我想一定有一些相对酷的解释(我对此一无所知)。


GCC不会对结构的元素重新排序,因为这将违反C标准。C99标准第6.7.2.1节规定:

Within a structure object, the non-bit-?eld members and the units in which bit-?elds
reside have addresses that increase in the order in which they are declared.


结构经常被用来表示二进制文件格式和网络协议的打包顺序。如果这样做的话,这个问题就会被打破。此外,不同的编译器将以不同的方式优化问题,并且将代码从两者链接在一起是不可能的。这根本不可行。


GCC在从源代码生成机器代码方面比我们大多数人都聪明;但是,如果它在重新安排结构方面比我们聪明的话,我会发抖,因为它是可以写入文件的数据。如果在GCC决定应该重新安排结构成员的另一个系统上读取以4个字符开始,然后具有4个字节整数的结构,那么它将是无用的。


GCCSVN确实有一个结构重组优化(fipa struct reorg),但是它需要整个程序分析,目前还不是很强大。


不说这是个好主意,但您当然可以编写依赖于结构成员顺序的代码。例如,作为一个黑客,人们通常将指向结构的指针作为他们想要访问的内部某个字段的类型,然后使用指针算法到达那里。对我来说,这是一个非常危险的想法,但我见过它,特别是在C++中强制变量被声明为私有的,当它在一个第三方库中的一个类中被公开访问,而不是公开封装的。重新排序成员将完全打破这一点。


C编译器不会自动打包结构,这完全是因为您提到的对齐问题。不在字边界上访问(大多数CPU上为32位)会对x86造成严重惩罚,并在RISC架构上造成致命陷阱。


您可能想尝试最新的gcc主干,或者正在进行活动开发的structreorg分支。

https://gcc.gnu.org/wiki/couldron2015?action=attachfile&do=view&target=olga+golovanevasky_uux+memory+layout+optimizations+of+structures+and+objects.pdf