可能重复:
为什么GCC不优化结构?
为什么C++不能使结构更紧凑?
请考虑以下32位x86计算机上的示例:
由于对齐约束,以下结构
struct s1 {
char a;
int b;
char c;
char d;
char e;
}
Run Code Online (Sandbox Code Playgroud)
如果成员被重新排序,则可以更有效地表示内存(12对8字节)
struct s2 {
int b;
char a;
char c;
char d;
char e;
}
Run Code Online (Sandbox Code Playgroud)
我知道C/C++编译器不允许这样做.我的问题是为什么语言是这样设计的.毕竟,我们最终可能会浪费大量的内存,而且struct_ref->b不会关心差异.
编辑:谢谢大家的非常有用的答案.您解释为什么由于语言的设计方式,重新排列不起作用.然而,它让我想到:如果重新排列是语言的一部分,这些论点是否仍然有效?让我们说有一些指定的重新排列规则,我们至少需要这个规则
我一个接一个地论证你的论点:
低级别的数据映射,"最惊喜的元素":只写你的结构以紧身款式自己(像@佩里的回答),并没有发生任何改变(要求1).如果由于一些奇怪的原因,你想要内部填充,你可以使用虚拟变量手动插入,和/或可能有关键字/指令.
编译器差异:要求3消除了这种担忧.实际上,从@David Heffernan的评论来看,我们今天似乎遇到了这个问题,因为不同的编译器填充不同?
优化:重新排序的重点是(内存)优化.我在这看到很多潜力.我们可能无法一起删除填充,但我没有看到重新排序如何以任何方式限制优化.
类型铸造:在我看来,这是最大的问题.不过,应该有办法解决这个问题.由于规则是用语言修复的,编译器能够弄清楚成员的重新排序方式,并做出相应的反应.如上所述,在您想要完全控制的情况下,始终可以防止重新排序.此外,要求2确保类型安全代码永远不会中断.
我认为这样的规则有意义的原因是因为我发现按结构内容而不是按类型对结构成员进行分组更为自然.当我有很多内部结构时,编译器也更容易选择最适合我的顺序.最佳布局甚至可能是我无法以类型安全的方式表达的布局.另一方面,它似乎使语言更复杂,这当然是一个缺点.
请注意,我不是在谈论改变语言 - 只有它可以(/应该)设计不同.
我知道我的问题是假设的,但我认为讨论提供了对机器和语言设计较低层次的更深入的了解.
我在这里很新,所以我不知道是否应该为此产生一个新问题.请告诉我是否是这种情况.
我有一个C#背景.我非常喜欢像C这样的低级语言.
在C#中,struct默认情况下由编译器布局内存.编译器可以隐式地重新排序数据字段或填充字段之间的附加位.因此,我必须指定一些特殊属性来覆盖此行为以获得精确布局.
AFAIK,C struct默认情况下不重新排序或对齐a的内存布局.但是,我听说有一个很难找到的例外.
什么是C的内存布局行为?什么应该重新订购/对齐而不是?
在尝试为未来的C程序创建内存管理器时,我遇到了这个问题:
例如,考虑以下结构.
typedef struct {
int field1;
int field2;
char field3;
} SomeType;
Run Code Online (Sandbox Code Playgroud)
分配时,字段的内存地址是否在字段field1,field2,field3中?或者这不保证?
我试图了解对象如何在汇编级别工作.对象如何存储在内存中,以及成员函数如何访问它们?
(编者注:原始版本过于宽泛,并且首先对装配和结构的工作方式产生了一些困惑.)