Ok.. för att utröna påverkan av det allokerade utrymmet på stacken så testade jag följande funktioner i vc6:
1
void f(){
cout << "tjo";
int v = 2;
if(v==1){
double t = 2;
}
if(v==2){
int p = 3;
}
}
2
void f(){
double t;
int p;
int v = 2;
cout << "tjo";
if(v==1){
t = 2;
}
if(v==2){
p = 3;
}
}
Vilket med ditt resonemang (för att spara utrymme på stacken) borde ge att en 4 bytes mindre stack allokerades. Men:
1
5: void f(){
00401150 push ebp
00401151 mov ebp,esp
00401153 sub esp,50h
00401156 push ebx
00401157 push esi
00401158 push edi
00401159 lea edi,[ebp-50h]
0040115C mov ecx,14h
00401161 mov eax,0CCCCCCCCh
00401166 rep stos dword ptr [edi]
6: cout << "tjo";
00401168 push offset string "tjo" (0043501c)
0040116D push offset std::cout (0043c8b8)
00401172 call @ILT+145(std::operator<<) (00401096)
00401177 add esp,8
7: int v = 2;
0040117A mov dword ptr [ebp-4],2
8:
9: if(v==1){
00401181 cmp dword ptr [ebp-4],1
00401185 jne f+45h (00401195)
10: double t = 2;
00401187 mov dword ptr [t],0
0040118E mov dword ptr [ebp-8],40000000h
11: }
12: if(v==2){
00401195 cmp dword ptr [ebp-4],2
00401199 jne f+52h (004011a2)
13: int p = 3;
0040119B mov dword ptr [p],3
14: }
15: }
004011A2 pop edi
004011A3 pop esi
004011A4 pop ebx
004011A5 add esp,50h
004011A8 cmp ebp,esp
004011AA call __chkesp (00408eb0)
004011AF mov esp,ebp
004011B1 pop ebp
004011B2 ret
2
5: void f(){
00401150 push ebp
00401151 mov ebp,esp
00401153 sub esp,50h
00401156 push ebx
00401157 push esi
00401158 push edi
00401159 lea edi,[ebp-50h]
0040115C mov ecx,14h
00401161 mov eax,0CCCCCCCCh
00401166 rep stos dword ptr [edi]
6: double t;
7: int p;
8: int v = 2;
00401168 mov dword ptr [ebp-10h],2
9: cout << "tjo";
0040116F push offset string "tjo" (0043501c)
00401174 push offset std::cout (0043c8b8)
00401179 call @ILT+145(std::operator<<) (00401096)
0040117E add esp,8
10:
11: if(v==1){
00401181 cmp dword ptr [ebp-10h],1
00401185 jne f+45h (00401195)
12: t = 2;
00401187 mov dword ptr [ebp-8],0
0040118E mov dword ptr [ebp-4],40000000h
13: }
14: if(v==2){
00401195 cmp dword ptr [ebp-10h],2
00401199 jne f+52h (004011a2)
15: p = 3;
0040119B mov dword ptr [ebp-0Ch],3
16: }
17: }
004011A2 pop edi
004011A3 pop esi
004011A4 pop ebx
004011A5 add esp,50h
004011A8 cmp ebp,esp
004011AA call __chkesp (00408eb0)
004011AF mov esp,ebp
004011B1 pop ebp
004011B2 ret
Om man betraktar raderna med "sub esp,xxx" som betyder allokerande av stacken i funktionen i båda fallen, ser man att den är lika stor i båda fallen (0x50h). Vidare är instruktionerna för 'double' variabeln lika.. vilka i sig är "avancerade datatyper" då flyttalsprocessorn får lite rutiner och det utförs mera nyttjande av klockcyklar. Dessa torde vara lika i båda fallen och det faller utanför allokerande & den intressanta tidsrymden. När det gäller int'arna finns en skillnad. Den som är deklarerad lokalt i scope har en label som adress mot den som är pekad med en fix adress mot stacken. Anledningen som jag ser det är precis som jag tidigare skrev - variabeln får den adressen som är ledig - på stacken. (som i bägge fallen var lika stor).
Därvid anser jag att det är mer eller mindre fastställt att "sparandet" av minne är ett mer intelligent beteende än vad kompilatorn klarar och således en inte riktigt sanningsenligt. Påståendet om att det sparas tid kan jag hålla med om, men då på utvecklingsstadiet och inte under programkörning.
Att egna datatyper skulle förändra beteendet på maskinkodsnivån såpass att den grundläggande stackhanteringen åsidosätts är föga troligt - men vem vet? Du kanske har illustrerande svar på det, Sang-drax?
red
stavfel
tillägg 25/5:
En int och en double belastar inte stacken särskilt mycket så jag gjorde om testet med att låta bägge variablerna vara arrays av storlek 1024 istället. Resultatet blev dock fortfarande detsamma i båda fallen men storleken ökades (naturligtvis) från 50h till 3044h.
*kommentar:
Det som jag finner udda är storleken på stacken. 1024 * 4 * 2 ger 0x2000 och inte 0x3044... varför allokeras 0x1040 extra (-4 för int v)? Resultatet är iofs lika i båda fallen, men ändock slösas(?) det exponentiellt med utrymme. Är detta fenomen kompilatorspecifikt eller finns det en naturlig förklaring som jag ivf inte ser?