2016-04-07 15 views
1

Nach dem Lesen der folgenden question, verstehe ich, dass es so etwas nicht gibt (zumindest nicht "tragbar").Wie schreibe ich eine Funktion, die einen Zeiger auf den Stapel zurückgeben

Jedoch habe ich auf den folgenden piece of code von Mono Code-Basis am Darstellern, die einen Zeiger auf den Stapel zurück:

static void * 
return_stack_ptr() 
{ 
    gpointer i; 
    return &i; 
} 

Ich bin überrascht, dass der obige Code auch auf Bogen wie PowerPC arbeiten kann, würde ich habe angenommen, das würde nur auf x86 (und vielleicht nur gcc) funktionieren.

Wird dies mit PowerPC funktionieren?

+1

Es gibt keine portable Funktion, die einen Zeiger auf den Stapel in C zurückgeben könnte. Es gibt nur Grade von Unportabilität. –

+0

Diese Art von Zeug ist Plattform und Compiler abhängig. –

+0

Der PowerPC ABI hat die Idee von Stapelspeicher, aber Ihr Compiler kann wählen, Variable 'i' in einen anderen Speicher als den Stapel zu legen. Trotzdem würde ich sagen, dass es mit jedem gängigen PowerPC-Compiler funktioniert. – atturri

Antwort

4

Der Zweck des Stapels ist die Unterstützung von Funktionsaufrufen und lokalen Variablen. Wenn Ihr System über einen Stack verfügt, wird dieser verwendet und die lokale Variable dort zugeordnet. Es ist also sehr vernünftig anzunehmen, dass die Adresse der lokalen Variablen irgendwo im Stapel liegt. Dies ist nicht spezifisch für x86 oder gcc - es ist eine ziemlich allgemeine Idee.

Verwenden Sie jedoch einen Zeiger auf eine Variable, die nicht vorhanden ist (d. H. Nachdem es den Gültigkeitsbereich verlässt), ist Undefined Behavior. Es kann also nicht garantiert werden, dass diese Funktion irgendeinen Sinn ergibt. In der Tat könnte ein "cleverer" Compiler erkennen, dass Ihr Programm ein nicht definiertes Verhalten verwendet, und Ihren Code durch ein No-Op ersetzen (und es eine "Leistungsoptimierung" nennen).

Alternativ könnte ein "weiser" Compiler erkennen, dass Ihre Funktion einen Zeiger auf den Stapel zurückgibt und ihn stattdessen mit einem Hardware-Stack-Zeiger verknüpft.

Keine der Optionen ist garantiert - dieser Code ist nicht übertragbar.

+2

Beachten Sie, dass der bloße Akt des _having_ eines einmal gültigen Pointers nicht UB ist. Dies ist beispielsweise der normale Zustand nach dem 'free (ptr)'. – MSalters