W pierwszej odpowiedzi here dodaje wspomniano o pamięci stosu w C++:C++: W jaki sposób kompilator wie, ile pamięci należy przydzielić dla każdej ramki stosu?
Gdy funkcja jest wywoływana, blok jest zarezerwowany na szczycie stosu dla zmiennych lokalnych i niektórych danych księgowych.
To ma sens na najwyższym poziomie, i czyni mnie ciekawi jak inteligentne kompilatory są przy przyznawaniu tej pamięci w sobie, biorąc pod uwagę kontekst this question: Ponieważ szelki sami nie są ramki stosu w C (Zakładam, że dotyczy to również C++), chcę sprawdzić, czy kompilatory optymalizują pamięć zarezerwowaną na podstawie zakresów zmiennych w ramach jednej funkcji.
Poniżej jestem przy założeniu, że stos wygląda tak przed wywołaniem funkcji:
--------
|main()|
-------- <- stack pointer: space above it is used for current scope
| |
| |
| |
| |
--------
A potem następującym po wywołaniu funkcji f()
:
--------
|main()|
-------- <- old stack pointer (osp)
| f() |
-------- <- stack pointer, variables will now be placed between here and osp upon reaching their declarations
| |
| |
| |
| |
--------
Na przykład, biorąc pod uwagę ta funkcja:
void f() {
int x = 0;
int y = 5;
int z = x + y;
}
Przypuszczalnie po prostu przydzieli 3*sizeof(int)
+ dodatkowe obciążenie dla księgowości.
Jednak to, co o tej funkcji:
void g() {
for (int i = 0; i < 100000; i++) {
int x = 0;
}
{
MyObject myObject[1000];
}
{
MyObject myObject[1000];
}
}
Ignorowanie optymalizacje kompilatora, który może Elide wiele rzeczy w wyżej ponieważ naprawdę nie robią nic, jestem ciekaw co następuje w drugim przykładzie:
- Dla pętli
for
: czy przestrzeń na stosie będzie wystarczająco duża, aby zmieściła się we wszystkich 100000 ints? - Co więcej, czy przestrzeń na stosie zawiera
1000*sizeof(MyObject)
lub2000*sizeof(MyObject)
?
Ogólnie: czy kompilator uwzględnia zakres zmienny przy określaniu wymaganej ilości pamięci dla nowej ramki stosu przed wywołaniem określonej funkcji? Jeśli jest to zależne od kompilatora, jak robią to niektóre dobrze znane kompilatory?
Para '{}' to jeden zakres. Pętla używa tej samej pamięci dla 'x', a dwie tablice' myObject' nie istnieją w tym samym czasie. – LogicStuff
Dlaczego konieczne jest przydzielenie miejsca dla '100000' int, kiedy może ponownie użyć tego samego miejsca? To samo dotyczy tablic. –
Kompilator analizuje każdy zakres funkcji, a zarezerwowana przestrzeń to maksymalna przestrzeń wszystkich zakresów, które mogą istnieć w tym samym czasie. –