Почему так много места выделяется в стеке?

Этот вопрос исходит из ответа на вопрос о переполнении стека Почему книги говорят: "компилятор выделяет пространство для переменных в памяти" ?, где я пытался продемонстрировать OP что происходит, когда вы выделяете переменную в стеке и как компилятор генерирует код, который знает размер памяти для распределения. По-видимому, компилятор выделяет гораздо больше места, чем нужно.

Однако при компиляции следующих

#include <iostream>
using namespace std;

int main()
{
    int foo;
    return 0;
}

Вы получаете следующий выход ассемблера с Visual С++ 2012, скомпилированный в режиме отладки без каких-либо оптимизаций:

int main()
{
00A31CC0  push        ebp
00A31CC1  mov         ebp,esp
00A31CC3  sub         esp,0CCh  // Allocates 204 bytes here.
00A31CC9  push        ebx
00A31CCA  push        esi
00A31CCB  push        edi
00A31CCC  lea         edi,[ebp-0CCh]
00A31CD2  mov         ecx,33h
00A31CD7  mov         eax,0CCCCCCCCh
00A31CDC  rep stos    dword ptr es:[edi]
   int foo;
   return 0;
00A31CDE  xor         eax,eax
}

Добавление еще одной int в мою программу делает вышеприведенную строку комментария следующей:

00B81CC3  sub         esp,0D8h // Allocate 216 bytes

Вопрос, поставленный @JamesKanze в моем ответе, связанный сверху, является причиной того, что компилятор, и, по-видимому, это не только Visual С++ (я не делал эксперимент с другим компилятором), соответственно, 204 и 216 байтов, где в в первом случае ему всего четыре, а во втором - только восемь?

Эта программа создает 32-битный исполняемый файл.

С технической точки зрения, почему ему может понадобиться выделить 204 байта вместо 4?

EDIT:

Вызывая две функции и создавая double и два int в основном, вы получаете

 01374493  sub         esp,0E8h  // 232 bytes

Для той же программы, что и для вышеперечисленного, она делает это в режиме деблокирования (без оптимизации):

 sub    esp, 8                // Two ints
 movsd  QWORD PTR [esp], xmm0 // I suspect this is where my `double` goes

Ответ 1

Это дополнительное пространство генерируется опцией компиляции /Zi. Что позволяет Edit + Continue. Дополнительное пространство доступно для локальных переменных, которые вы можете добавить при редактировании кода во время отладки.

Вы также видите эффект /RTC, он инициализирует все локальные переменные до 0xcccccccc, так что легче диагностировать проблемы из-за забывания инициализировать переменные. Конечно, ни один из этих кодов не генерируется в настройках конфигурации выпуска по умолчанию.