2009-11-06 5 views
10

Ich habe eine Frage zu folgendem C-Code:Wann ist Stack-Speicherplatz für lokale Variablen reserviert?

void my_function() 
{ 
    int i1; 
    int j1; 

    // Do something... 

    if (check_something()) 
    { 
     int i2; 
     int j2; 

     // Do something else... 
    } 

    // Do some more stuff... 
} 

Gibt es irgendwelche Garantien, wenn Stapelspeicher zugeordnet/freigegeben für i2 und j2 oder auf dem Compiler abhängt? Ich würde erwarten, dass der Stack-Pointer nach unten korrigiert wird, wenn i2 und j2 in den Gültigkeitsbereich kommen und wieder angepasst werden, wenn sie den Gültigkeitsbereich verlassen, aber dann dachten einige Compiler, das Ganze "zu optimieren" und Variablen in einem verschachtelten Scope zu berücksichtigen Die Funktion wird zuerst eingegeben.

Ich weiß, ich kann den von meinem Compiler generierten Assembler-Code betrachten, habe mich aber gefragt, ob die Implementierung dem Compiler überlassen werden kann.

Danke!

+5

Beachten Sie auch, dass Variablen Registern zugeordnet werden können ... – unwind

Antwort

6

Der Compiler kann frei tun, was er will, solange die Semantik der Sprache reserviert ist. Mit anderen Worten, i2 und j2 können an Speicherorte gebunden werden, bevor die Ausführung den Eingangspunkt ihres Blocks erreicht, und können jederzeit unbegrenzt sein, solange dies die Semantik Ihres Codes nicht beeinflusst.

8

Es gibt keine Garantien.

Verschiedene Optimierungs-Flags führen wahrscheinlich zu unterschiedlichen Methoden zum Speichern von Variablen.

Der Compiler kann sogar 1 oder mehr Variablen verwenden, die den Stack überhaupt nicht verwenden und sie für die gesamte Dauer der Funktionsausführung in Registern behalten.

+0

+! für keine Garantien. –

4

Wie ich verstehe, können Sie auch keine Garantie erhalten, dass diese Variablen auf dem Stack zugewiesen werden, sie könnten in Registern gespeichert werden.

Was Sie wirklich hier beeinflussen könnten:

Compiler
  • Tipps Variable zu setzen, indem Sie Register Schlüsselwort zu registrieren.

  • Help Compiler mit variablen Umfang lokalisierende durch Erklärung gegenüber so spät Ort zu bewegen, wie Sie können:

 
    int f(void) 
    { 
     /* var1 and var2 probably use the same place for storage. */ 
     { 
      int var1; 
      /* ... do something */ 
     } 

     { 
      int var2; 
      /* ... do something */ 
     } 
    } 


  • Auch gegeben definierten Umfang Verzögerung Initialisierung:
 
{ 
    int i; /* Yes, you must declare it at the begin of block. 

    /* Do something... */ 

    i = START_VALUE; 
    /* But you need it only here and below... */ 
} 
0

Wenn "check_something()" leicht zu 0 ausgewertet werden kann, wird der gesamte Block mit einem ausreichend hohen Optimierungsgrad optimiert. Ja, es ist compilerabhängig. Wenn Sie den Rückgabewert eines Funktionsaufrufs überprüfen, wird dieser im Allgemeinen nicht optimiert. Der beste Weg, dies zu erreichen, wäre, es zu kompilieren und tatsächlich die Disassemblierung der Datei zu betrachten, um zu überprüfen, was Ihrer Meinung nach tatsächlich passiert.

3

Wenn die Variablen auf den Stack gelegt werden, wird der Stack-Speicherplatz am Anfang der Funktion vor der ersten Anweisung in der Funktion zugewiesen.Der Stapelzeiger wird um die Gesamtanzahl der Bytes nach oben oder unten bewegt, um alle lokalen Variablen zu speichern.