SmacL
SmacL

Reputation: 22922

Are stack frames allocated and deallocated with scope?

Following on from a previous question here I've been looking at the output from the VS2015 code analysis and see a warning for high stack usage in a function that can be simplified as follows;

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;
   }
}

The analysis warns me that I'm using 20,000 bytes of stack in MyFunc. Is this the case, in that all stack variables are allocated at function entry and deallocated at function exit, rather than as they are constructed and destructed with scope? Just curious (but not quite curious enough to go wading through the assembly output ;) ) A related question here doesn't quite give me the answer I'm looking for.

Upvotes: 1

Views: 425

Answers (1)

Potatoswatter
Potatoswatter

Reputation: 137850

Stack frame allocation is at the compiler's discretion. Most compilers do not try to isolate local scopes with large variables, but most compilers do provide a facility like alloca or C99 VLAs which dynamically extend an existing stack frame. So architectural issues are unlikely to be in play; it is purely a matter of implementation details.

You can enclose local scopes in lambda expressions to encourage the compiler to provide such isolation:

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

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

Still, nothing is guaranteed.

You can use the godbolt.org online compiler to see machine code disassembly for such examples. It looks like this trick works on GCC, but on Clang it only works with optimization -O1 or less, and on Intel's compiler it only works with -O0.

Upvotes: 1

Related Questions