2013-09-05 9 views
5

Von der Programmierung in Lua Buch 3. Auflage Seite 38Warum können Gotos in Lua nicht aus Funktionen springen?

Aufgabe 4.5: Können Sie erklären, warum Lua die Einschränkung, dass ein goto kann nicht aus einer Funktion springen hat? (Hinweis: Wie würden Sie diese Funktion implementieren)

Ich habe ein paar Vermutungen, warum es so sein:

  • Wenn Sie von einer Funktion in die andere springen und die zweite zurückkehrt, Wohin geht der PC?
  • Wenn Sie haben, aber f eine goto nach dieser Zeile Code tut, was ist der Wert von a?
  • Ist es nicht möglich, ein Standardverhalten aufgrund der Aufrufkonventionen der verschiedenen Plattformen zu definieren?

Ich frage mich, wie der Autor diese Frage beantworten würde. Vielleicht schicke ich ihm eine E-Mail.

Hat in der Zwischenzeit jemand andere Ideen?

+2

Ich denke, es ist [wegen der Velociraptoren] (http://xkcd.com/292/). – Renan

+1

Plattformprobleme sollten keine Rolle spielen. Lua wird nicht nur in ANSI C implementiert, sondern Lua-Funktionen verwenden den C-Stack nicht für ihre Stack-Frames (dies ist notwendig, um Coroutinen portabel implementieren zu können). Ansonsten bist du auf dem richtigen Weg - mach dir keine Sorgen über die Suche nach einer kanonischen Antwort, denn es gibt viele Gründe, gotos so einzuschränken. – hugomg

Antwort

9

Ihre Vermutungen deuten auf die Antwort hin. Der Grund dafür ist, dass die goto-Anweisung und ihr Ziel im selben Stack-Frame liegen müssen. Der Programmkontext vor und nach der goto muss identisch sein, sonst läuft der Code, zu dem gesprungen wird, nicht in seinem korrekten Stack-Frame und sein Verhalten ist nicht definiert. goto in C hat die gleichen Einschränkungen aus den gleichen Gründen.

Die C-Standardbibliothek bietet auch longjmp() und setjump(), mit denen Sie eine Form von "Goto" aus dem aktuellen Stapelrahmen implementieren können. setjmp() speichert den aktuellen Stapelkontext. Sie können dann longjmp() aufrufen, um den Stack wieder zu dem Punkt zurückzurollen, an dem Sie setjmp() aufgerufen haben. Nach der Funktion, die setjump() aufgerufen hat, können Sie longjmp() nicht aufrufen.

+0

Lua sagt: 1. Kann nicht innerhalb eines Blocks springen. 2. Kann nicht aus Funktionen springen. 3. Kann nicht in den Bereich lokaler Variablen springen. Regel # 1 erlaubt bereits den Sprung in Funktionen. Wenn also Regel # 2 nicht existiert, dann können wir nur in den globalen Bereich springen. Stellt der Sprung in den globalen Rahmen immer noch Probleme dar? Hat der globale Bereich sogar einen richtigen Stack-Frame? –

+1

Der globale Bereich ist eigentlich eine anonyme Funktion, deren Hauptteil der gesamte "Chunk" an "lua_load()" übergeben wird. Der globale Gültigkeitsbereich kann weiterhin lokale Variablen enthalten, und es gelten alle die gleichen Eckfälle. Auf der [Lua-L] (http://news.gmane.org/gmane.comp.lang.lua.general) -Liste gab es in den Jahren 2010 und 2011 eine ausführliche Diskussion über 'goto', als Lua 5.2-Veröffentlichungen das erste Mal auf dem Markt waren Probleme rund um 'goto' und verwandte Keywords wie' continue'. Durchsuchen Sie die Archive nach Wörtern wie "goto", "scope", "block", "local". – RBerteig

Verwandte Themen