2017-02-05 3 views
1

Следующее из previous question here Я смотрю на результат анализа кода VS2015 и вижу предупреждение о высоком использовании стека в функции, которая может быть упрощена следующим образом;Являются ли фреймы стека выделенными и освобожденными от объема?

class base 
{ 
public: 
    virtual void Process(); 
    Buffer[10000]; 
}; 

class derived1 : public base 
{ 
public: 
    void Process(); 
} 

class derived2 : public base 
{ 
public: 
    void Process(); 
} 

void MyFunc(int x) 
{ 
    switch(x) 
    { 
    case 0: 
    { 
     derived1 x; 
     x.Process(); 
    } break; 
    case 1: 
    { 
     derived2 y; 
     y.Process(); 
    } break; 
    } 
} 

Анализ предупреждает меня, что я использую 20000 байт стека в MyFunc. В этом случае все переменные стека выделяются при записи функции и освобождаются при выходе функции, а не по мере их создания и разрушаются с помощью области видимости? Просто любопытно (но не достаточно любопытно, чтобы пройти через сборку;)) related question здесь не совсем дает мне ответ, который я ищу.

+1

Зависит от компилятора и его оптимизации. Это не то, что прямо предусмотрено стандартом. – Mat

ответ

1

Распределение кадров стека по усмотрению компилятора. Большинство компиляторов не пытаются изолировать локальные области с большими переменными, но большинство компиляторов предоставляют объект, такой как alloca или C99 VLAs, которые динамически расширяют существующий стек стека. Таким образом, архитектурные проблемы вряд ли будут играть; это чисто вопрос реализации.

Вы можете вложить локальные области действия в лямбда-выражений поощрять компилятор, чтобы обеспечить такую ​​изоляцию: не

switch(x) 
    { 
    case 0: 
    []{ 
     derived1 x; 
     x.Process(); 
    }(); break; 

    case 1: 
    []{ 
     derived2 y; 
     y.Process(); 
    }(); break; 
    } 

Тем не менее, ничего гарантировано.

Вы можете использовать онлайн-компилятор godbolt.org, чтобы увидеть разборку машинного кода для таких примеров. Похоже, этот трюк работает на GCC, но на Clang он работает только с оптимизацией -O1 или меньше, а на компиляторе Intel он работает только с -O0.