Seite 2 von 2
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Verfasst: 15.12.2011 15:21
von CSHW89
ts-soft hat geschrieben:Abgesehen davon, das dieser Code bei mir einen ASM error wirft, warum wollt Ihr immer den Stack
bereinigen, das macht PB doch bei einem ProcedureReturn automatisch, sollte also vollkommen
unnötig sein?
Abgesehen davon, das dieser Code bei mir einen ASM error wirft, warum wollt Ihr immer den Stack
bereinigen, das macht PB doch bei einem ProcedureReturn automatisch, sollte also vollkommen
unnötig sein?
Kann sein, dass du den Code kopiert hast, bevor ich ihn editiert hab. Hab erst "Global SaveStack" vergessen. Und es ging ja darum, dass man direkt mehrere Rekursionstiefen zurückspringt, nicht bei einer Tiefe von 10000, 10000 zurückspringen muss.
NicTheQuick hat geschrieben:Nein, PB macht das nicht, wenn man einfach so mit einem Goto aus einer Procedure heraus springt.
Doch, wenn man selber den Stack repariert.
lg Kevin
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Verfasst: 15.12.2011 15:26
von NicTheQuick
Naja, angenommen du bist schon in der 10. Rekursion. Dann springst du mit einem ProcedureReturn einfach nur zurück in die 9. Rekursion und musst so weiter machen, bis du in der 0. Rekursion bist und dann kannst du ins Hauptprogramm zurück. Bei jedem ProcedureReturn wird der Stackpointer dann wieder entsprechend zurück gesetzt. Mit einem Goto hast du den Vorteil, dass du direkt raus springen kannst ohne den umständlichen Weg zu gehen immer nur Schritt für Schritt zu gehen. Wichtig ist dann aber den Stackpointer auch wieder richtig zurück zu setzen. Im Beispiel von CSHW89 geht das mit einem kleinen ASM-Befehl anstatt 10 mal den Pointer Stück für Stück zurück zu setzen.
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Verfasst: 15.12.2011 16:17
von alen
Hallo Community,
ich wusste nicht das ich mit meiner Frage so eine Welle schlage. Scheint aber wirklich ein prinzipielles Problem zu sein. Der Anwendungsfall sollte dazu dienen, rekursiv die Registry zu durchsuchen bis man aus einen definierten Wert trifft und daraufhin dann die ganze Rekursion komplett, unverzüglich und sauber verlässt. Eine Exception auslösen käme der Sache schon nahe. Nur das gibt es im PB nicht.
Anwendung auf den Punkt gebracht:
- Suche den kompletten Pfad
- Wenn Wert gefunden Suche sofort beenden
- Fund zurückliefern
Das ist doch eigentlich ein gängiger Anwendungsfall. Sollte in der Praxis öfter vorkommen.
Wie würdet Ihr sowas lösen ?
Grüße
Alen
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Verfasst: 15.12.2011 16:26
von ts-soft
NicTheQuick hat geschrieben:Naja, angenommen du bist schon in der 10. Rekursion. Dann springst du mit einem ProcedureReturn einfach nur zurück in die 9. Rekursion
Nach dem, was ich im engl. Forum von Fred gelesen habe, ist dem eben nicht so! PB bereinigt das autom.,
oder ich habe da was durcheinander gebracht, was ja auch mal vorkommen könnte

Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Verfasst: 15.12.2011 16:32
von STARGÅTE
Hier der Weg über Rekursion:
Code: Alles auswählen
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
#DirectoryDelimiter$ = "\"
CompilerElse
#DirectoryDelimiter$ = "/"
CompilerEndIf
Procedure.s FindFile(Path.s, FileName.s)
Protected Result.s
Protected Directory.i = ExamineDirectory(#PB_Any, Path.s, "*")
If Directory
Debug Path
If Right(Path, 1) <> #DirectoryDelimiter$
Path + #DirectoryDelimiter$
EndIf
While NextDirectoryEntry(Directory)
Select DirectoryEntryType(Directory)
Case #PB_DirectoryEntry_Directory
If DirectoryEntryName(Directory) = "." Or DirectoryEntryName(Directory) = ".."
Continue
EndIf
Result = FindFile(Path+DirectoryEntryName(Directory), FileName)
If Result
Break
EndIf
Case #PB_DirectoryEntry_File
If DirectoryEntryName(Directory) = FileName
Result = Path+DirectoryEntryName(Directory)
Break
EndIf
EndSelect
Wend
FinishDirectory(Directory)
EndIf
ProcedureReturn Result
EndProcedure
Debug FindFile("C:", "Beispiel.txt")
C:\Dokumente und Einstellungen\***\Beispiel.txt
Wie schon von NicTheQuick angedeutet, kann man auch diese Rekursion in eine Iteration umwandeln.
Dazu muss müssen dann nur die Directory-Nummern in einer Liste abgespeichert werden, sodass sie ordnungsgemäß wieder freigegeben werden können.
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Verfasst: 15.12.2011 16:50
von ts-soft
@STARGÅTE
Wie ich NickTheQuick verstanden habe, würde Dein Code einen Stacküberlauf verzapfen, was aber nach
meinem Verständnis nicht der Fall ist.
Was ist denn nun richtig?
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Verfasst: 15.12.2011 20:25
von STARGÅTE
Stacküberlauf gibt es nur, wenn die Rekursionstiefe zu groß wird (ca 80.000 bei einem Parameter).
Da hier die Tiefe gleich der Ordnertiefe entspricht, wird es also nie passieren.
Wie oft eine Prozedur sich selbst in einer Tiefe aufruft ist egal, da es ja immer stück für stück geht und erst die erste komplett in die Tiefe geht, wieder zurück und dann die nächste.
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Verfasst: 20.12.2011 21:26
von remi_meier
STARGÅTE hat geschrieben:Stacküberlauf gibt es nur, wenn die Rekursionstiefe zu groß wird (ca 80.000 bei einem Parameter).
Da hier die Tiefe gleich der Ordnertiefe entspricht, wird es also nie passieren.
Wie oft eine Prozedur sich selbst in einer Tiefe aufruft ist egal, da es ja immer stück für stück geht und erst die erste komplett in die Tiefe geht, wieder zurück und dann die nächste.
Hah, du bist nur noch nie auf einen rekursiven
Symlink gestossen
@ts-soft:
Wenn du nur ProcedureReturn verwendest, räumt PB natürlich selbst
auf und du solltest nie einen korrupten Stack vorfinden. Das Problem
sind nur Gotos innerhalb einer Prozedur, die nach aussen springen
(gleiches Problem bei OnErrorGoto).
Wenn man Stack-Überläufe produziert, hat man meist falsch programmiert.
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Verfasst: 20.12.2011 22:42
von ts-soft
@remi_meier
Danke, genauso hatte ich das bisher auch immer verstanden und Goto, sowie OnErrorGoto
sind für mich genauso wichtig, wie die FTP
