Зачем программе на C ++ выделять для локальных переменных больше памяти, чем нужно в худшем случае?

Вдохновленный этим вопросом .

Очевидно в следующем коде:

#include 

int _tmain(int argc, _TCHAR* argv[])
{
    if( GetTickCount() > 1 ) {
        char buffer[500 * 1024];
        SecureZeroMemory( buffer, sizeof( buffer ) );
    } else {
        char buffer[700 * 1024];
        SecureZeroMemory( buffer, sizeof( buffer ) );
    }
    return 0;
}

скомпилирован с размером стека по умолчанию (1 мегабайт) с помощью Visual C ++ 10 с оптимизацией на (/ O2) a Переполнение стека происходит из-за того, что программа пытается выделить в стеке 1200 килобайт.

Приведенный выше код, конечно, слегка преувеличен, чтобы показать проблему - использует большое количество стека довольно глупым способом. Однако в реальных сценариях размер стека может быть меньше (например, 256 килобайт), и может быть больше ветвей с меньшими объектами, которые вызовут общий размер выделения, достаточный для переполнения стека.

Это не имеет смысла. В худшем случае будет 700 килобайт - это будет кодовый путь, который создает набор локальных переменных с наибольшим общим размером на этом пути. Обнаружение этого пути во время компиляции не должно быть проблемой.

Таким образом, компилятор создает программу, которая пытается выделить даже больше памяти, чем в худшем случае. Согласно , этот ответ LLVM делает то же самое.

Это могло быть недостатком в компиляторе или могла быть какая-то реальная причина для этого. Я имею в виду, что, возможно, я просто не понимаю чего-то в дизайне компиляторов, что могло бы объяснить, почему такое распределение необходимо.

Почему компилятор хочет, чтобы программа выделяла больше памяти, чем требуется коду в худшем случае?

9
задан Community 23 May 2017 в 12:06
поделиться