Reputation: 22922
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
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