Компилятор (g++), как представляется, выделяет больше памяти для экземпляров классов, чем требуется

Я узнаю, как компиляторы представляют программы на С++ в сборке. У меня вопрос о том, что делает компилятор, о котором я не могу понять. Вот код С++:

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

int main() {
  Class1 cls;
}

Компиляция с "g++ -S" выводит это (я удалил все, кроме определения функции):

main:
    push    ebp
    mov     ebp, esp
    sub     esp, 16
    mov     eax, 0
    leave
    ret

Я не понимаю строку sub esp, 16. Зачем ему выделять 16 байтов для экземпляра этого класса, для которого требуется только 8, когда вы принимаете во внимание выравнивание структуры данных и добавление?

Это должно быть

[int i - 4 bytes][char ch - 1 byte][padding - 3 bytes]

Если это не так?

Когда я скомпилировал код с определением класса, включая двойной, т.е.

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

он по-прежнему выделял 16 байтов, что имело смысл в этом случае.

Итак, почему компилятор выделяет 16 байтов, когда ему требуется только 8?

Ответ 1

Это связано с выравниванием кадров стека, а не с выравниванием структуры.

Если вы сделали sizeof() для своих объектов, вы увидите, что вы ожидаете при выравнивании и дополнении структуры.

Однако стековые фреймы немного отличаются. В большинстве систем сегодня выравнивание стека составляет 16 байтов (или более) для размещения доступа к памяти SSE.