Рассмотрим следующий код:Как компилятор определяет необходимый размер стека для функции с генерируемыми временными циклами компилятора?
class cFoo {
private:
int m1;
char m2;
public:
int doSomething1();
int doSomething2();
int doSomething3();
}
class cBar {
private:
cFoo mFoo;
public:
cFoo getFoo(){ return mFoo; }
}
void some_function_in_the_callstack_hierarchy(cBar aBar) {
int test1 = aBar.getFoo().doSomething1();
int test2 = aBar.getFoo().doSomething2();
...
}
В строке, где getFoo() вызывается компилятор генерирует временный объект CFoo, чтобы быть в состоянии назвать doSomething1(). Является ли компилятор повторным использованием памяти стека, которая используется для этих временных объектов? Сколько памяти стека вызовет «some_function_in_the_callstack_hierarchy»? Он резервирует память для каждого созданного временного?
Мое предположение, что компилятор только резервирование памяти для одного объекта CFoo и повторное использование памяти для различных вызовов, но если добавить
int test3 = aBar.getFoo().doSomething3();
я могу видеть, что требуется размер стека для «some_function_in_the_callstack_hierarchy» больше и не только из-за дополнительной локальной переменной int.
С другой стороны, если я затем заменить
cFoo getFoo(){ return mFoo; }
со ссылкой (только для целей тестирования, так как возвращает ссылку на частный член не хорошо)
const cFoo& getFoo(){ return mFoo; }
он нужен путь меньше памяти стека, чем размер одного cFoo.
Так что для меня кажется, что компилятор резервирует дополнительную стек стека для каждого созданного временного объекта в функции. Но это было бы очень неэффективно. Может кто-нибудь объяснить это?
Это в значительной степени определяется реализацией. Даже не гарантируется, что объекты с автоматическим хранилищем будут созданы в стеке в первую очередь. – SingerOfTheFall
На всякий случай вы не убедились, что вы скомпилируете что-то вроде '-O2'. Анализ не оптимизированной сборки не очень полезен. – NathanOliver
Скомпилировано с -O1 – Matthias