系统要求某些基元与内存中的某些点对齐(对于4的倍数的字节,对于2的倍数的字节的短路,等等)。当然,这些可以被优化以浪费填充中的最小空间。
我的问题是GCC为什么不自动执行此操作?更明显的启发式(从最大尺寸要求到最小尺寸的订单变量)是否在某种程度上缺乏?一些代码是否依赖于其结构的物理排序(这是一个好主意)?
我只是问,因为GCC在很多方面都是超级优化的,但不是在这个方面,我认为必须有一些相对很酷的解释(我不知道)。
答案 0 :(得分:74)
gcc不会重新排序结构的元素,因为这会违反C标准。 C99标准的第6.7.2.1节规定:
在结构对象中,非位字段成员和位字段中的单位 驻留的地址会按声明的顺序增加。
答案 1 :(得分:25)
结构经常用作二进制文件格式和网络协议的打包顺序的表示。如果这样做会破坏。此外,不同的编译器会以不同的方式优化事物,并且将代码从两者链接在一起是不可能的。这根本不可行。
答案 2 :(得分:9)
GCC比我们大多数人从我们的源代码生产机器代码更聪明;然而,如果它比我们更聪明地重新安排我们的结构,我会颤抖,因为它的数据是例如可以写入文件。如果在GCC决定重新安排结构成员的另一个系统上读取,那么以4个字符开头然后具有4字节整数的结构将是无用的。
答案 3 :(得分:6)
gcc SVN确实有一个结构重组优化(-fipa-struct-reorg),但它需要整个程序分析,目前还不是很强大。
答案 4 :(得分:1)
C编译器不会自动打包结构正是因为你提到的对齐问题的。不在字边界上访问(大多数CPU上为32位)会对x86造成严重损失,并在RISC架构上造成致命陷阱。
答案 5 :(得分:1)
不是说这是个好主意,但你当然可以编写依赖于结构成员顺序的代码。例如,作为一个黑客,人们经常会将一个指向结构的指针作为他们想要访问的某个字段的类型,然后使用指针算法来实现。对我来说,这是一个非常危险的想法,但我已经看到它被使用,特别是在C ++中强制一个被声明为私有的变量,当它在第三方库的类中时是公开可访问的,并且不是公开封装的。重新排序成员将彻底打破这一点。
答案 6 :(得分:0)
您可能想尝试最新的gcc trunk或正在积极开发的struct-reorg-branch。