编译器(G ++)似乎为类的实例分配了比它需要的更多的内存

Gra*_*y S 10 c++ x86 assembly gcc compilation

我正在学习编译器如何在汇编中表示C++程序.我有一个关于编译器做的事情的问题,我无法理解.这是一些C++代码:

class Class1 {
public:
  int i;
  char ch;
};

int main() {
  Class1 cls;
}
Run Code Online (Sandbox Code Playgroud)

使用"g ++ -S"进行编译输出(我已经删除了除函数定义之外的所有内容):

main:
    push    ebp
    mov     ebp, esp
    sub     esp, 16
    mov     eax, 0
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

我不明白这条线sub esp, 16.为什么它会为此类的实例分配16个字节,当您考虑数据结构对齐和填充时,只需要8个字节?

它应该是

[int i - 4 bytes][char ch - 1 byte][padding - 3 bytes]
Run Code Online (Sandbox Code Playgroud)

不应该吗?

当我用类定义编译代码时也包括一个double,即

class Class1 {
public:
  int i;
  char ch;
  double dub;
}; 
Run Code Online (Sandbox Code Playgroud)

它仍然分配了16个字节,这在这种情况下是有意义的.

那么为什么编译器在需要8个字节时会分配16个字节呢?

Mys*_*ial 12

这与堆栈帧对齐有关,而与结构对齐无关.

如果您sizeof()对对象执行了操作,您将看到对结构对齐和填充的期望.

但是,堆栈帧略有不同.在当今的大多数系统中,堆栈对齐是16字节(或更多)以适应SSE存储器访问.

  • SSE是x86上的一组128位SIMD指令.寄存器长度为16个字节.因此堆栈需要与16字节对齐.(http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions) (2认同)