50

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

我的问题是为什么 GCC 不自动执行此操作?是否缺少更明显的启发式(从最大尺寸要求到最小尺寸的顺序变量)?某些代码是否依赖于其结构的物理顺序(这是个好主意)?

我只是问,因为 GCC 在很多方面都经过了超级优化,但在这方面却没有,而且我认为一定有一些相对酷的解释(我没有注意到)。

4

7 回答 7

79

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

在结构对象中,非位域成员和位域所在的单元的地址按声明顺序递增。

于 2008-09-22T23:13:43.637 回答
28

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

于 2008-09-22T22:48:40.950 回答
11

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

于 2008-09-22T22:56:53.990 回答
7

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

于 2008-10-31T19:11:25.470 回答
2

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

于 2008-09-22T22:50:58.543 回答
2

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

于 2009-02-18T19:18:47.507 回答
1

您可能想尝试最新的 gcc 主干或正在积极开发的 struct-reorg-branch。

https://gcc.gnu.org/wiki/cauldron2015?action=AttachFile&do=view&target=Olga+Golovanevsky_+Memory+Layout+Optimizations+of+Structures+and+Objects.pdf

于 2015-09-12T04:25:10.627 回答