Goto funktioniert nicht in einer Function ?

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

 

funkheld

Betreff: Goto funktioniert nicht in einer Function ?

BeitragFr, Feb 23, 2018 15:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo, guten Tag.

Das Goto funktioniert nicht in einer Funktion.
Es kommt eine Fehlermeldung. Was ist da bitte falsch

Code: [AUSKLAPPEN]

Function start_python()
    If text=""
       Goto weiter
     EndIf
        Print text
   #weiter
EndFunction


Danke.
Gruss
  • Zuletzt bearbeitet von funkheld am Fr, Feb 23, 2018 17:26, insgesamt einmal bearbeitet

Farbfinsternis

BeitragFr, Feb 23, 2018 16:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Was soll dieses Konstrukt denn bitte machen und warum hantierst Du mit "evil goto" rum? Lass die Bedingung einfach leer und Du landest automatisch bei Deinem "weiter".
Farbfinsternis.tv
 

funkheld

BeitragFr, Feb 23, 2018 17:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Hatte ich vergessen.
Ich wollte den tText nur Printen wenn etwas drin ist.

Gruss

Lobby

BeitragFr, Feb 23, 2018 17:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Vielleicht solltest du dann einfach deine Bedingung negieren und die Ausgabe in den Ausführungsblock stecken Smile
TheoTown - Eine Stadtaufbausimulation für Android, iOS, Windows, Mac OS und Linux

Midimaster

BeitragFr, Feb 23, 2018 18:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Da gibt es Code-technisch mehre interessante Lösungen.


Wie die Anderen ja schon geschrieben haben... einfach die If-Kondition umformulieren
BlitzMax: [AUSKLAPPEN]
Function start_python()
If text<>""
Print text
EndIf
EndFunction




Oft ist das "negieren" aber nur umständlich hinzubekommen. Da könnte man es dann so machen:

BlitzMax: [AUSKLAPPEN]
Function start_python()
If (text="") Or ( (Len(text)=1) And (Ucase(text)=text))
' nix machen
Else
Print text
EndIf
EndFunction



Und auch der sofortige RETURN aus einer Funktion ist oft sinnvoll:

BlitzMax: [AUSKLAPPEN]

Type TPlayer
Field text$
EndType

Global Player:TPlayer
...
Function start_python()
If Player=Null Return
...
Print Player.text
EndFunction
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
 

funkheld

BeitragFr, Feb 23, 2018 20:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für dien Info.

Warum hat man Goto eigentlich reingenommen in Blitzmax ?

Gruss

Mathias-Kwiatkowski

BeitragSa, Feb 24, 2018 2:21
Antworten mit Zitat
Benutzer-Profile anzeigen
goto wurde reingenomm und du kannst es sehr wohl benutzen nur wirst du irgendwann mit 50 gotos dich selbst verzetteln, darum wird dir jeder von goto abraten.
Skype: Anarchie1984
http://projektworks.de/maxbase/
Icq - Erneuert am 21.08.2017
Yahoo - Erneuert am 21.08.2017

Thunder

BeitragSa, Feb 24, 2018 12:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Du bist wahrscheinlich im Strict oder SuperStrict Modus (erkennbar am entsprechenden Befehl in einer der ersten Zeilen von deinem BlitzMax-Quelltext).
Das erklärt auch, warum du in einem deiner anderen Threads die Variable outfile nicht ohne Local/Global definieren konntest.

Goto ist durch den originalen BlitzMax-Compiler einfach für den Strict/SuperStrict-Modus gesperrt. D.h. du darfst den Befehl da nicht verwenden, weil jemand clever war und dachte, dass das eine gute Idee ist. Habe das in meinem Fork von BlitzMax herausgepatcht.
Hier ist der entsprechende Commit: https://bitbucket.org/chtisgit...?at=master

Ich glaube du hast gesagt, du hast BlitzMax selber gebaut? Dann kannst du einfach diese Zeile im Compiler löschen und ihn neukompilieren.

-------

Edit: Goto hat einige gute Einsatzzwecke, man muss aber dazusagen, dass einige davon in BlitzMax eleganter zu lösen sind. z.B. aussteigen aus verschachtelten schleifen:
BlitzMax: [AUSKLAPPEN]
#aussen
While True
For Local i = 0 To 10
If i = 3 Then
Exit aussen
EndIf
Next
Wend


Legitime Einsatzmöglichkeiten sind z.B. Freigabe von Ressourcen im Fehlerfall:
BlitzMax: [AUSKLAPPEN]
Function openConfig:String[]()
Local f:TStream = OpenFile("c:\config.txt")
If f = Null Then
Return Null
EndIf
Local options:String[]
While Not Eof(f)
' datei parsen
If error Then
Goto fehler
EndIf
' weiter parsen
If error2 Then
Goto fehler
EndIf
Wend

CloseFile f
Return options
#fehler
CloseFile f
Return Null
EndFunction


Auch wenn man diesen Stil eher nur in C code sieht. In C++ kann man das durch RAII vermeiden und in Go z.B. durch defer-Statements -- haben wir aber beides in BlitzMax nicht. Man könnte natürlich eine Exception werfen, aber obwohl es Exceptions in BlitzMax gibt, werden sie von den brl-Libs eigentlich nur für fatale Zustände verwendet, wenn ich mich nicht irre.
 

funkheld

BeitragSa, Feb 24, 2018 15:15
Antworten mit Zitat
Benutzer-Profile anzeigen
------------------------------------
Ich glaube du hast gesagt, du hast BlitzMax selber gebaut?
------------------------------------

Nein ich habe den Sourcecode von BlitzMax nur selber compiliert mit Mingw.

GRuu

Lobby

BeitragSa, Feb 24, 2018 18:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Genau das dürfte Thunder mit bauen meinen Smile
TheoTown - Eine Stadtaufbausimulation für Android, iOS, Windows, Mac OS und Linux
 

#Reaper

Newsposter

BeitragSa, Feb 24, 2018 22:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Ein Grund warum GoTo böse ist wäre, dass man extrem damit herumglitchen kann: Man kann zum Beispiel einfach aus einer Funktion aussteigen, ohne dass diese Ordnungsgemäß mittels Return oder eben "End Function" beendet wurde. Das würde den Stack zumindest in einen undefinierten oder eben "falschen" Zustand bringen und würde sogar auf Assembler-Ebene die Register der CPU so hinterlassen, als wenn man noch in der Funktion wäre. Was BMax dann noch weiter daraus macht wäre wohl relativ Random. Vorausgesetzt ich erinnere mich richtig? iIs schon alles ewig lange her.
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7

Thunder

BeitragSo, Feb 25, 2018 11:53
Antworten mit Zitat
Benutzer-Profile anzeigen
#Reaper hat Folgendes geschrieben:
Man kann zum Beispiel einfach aus einer Funktion aussteigen, ohne dass diese Ordnungsgemäß mittels Return oder eben "End Function" beendet wurde.


Ich glaube, was BB angeht kann das stimmen, aber in BlitzMax sind diese Labels lokal, d.h. du kannst nur innerhalb der momentanen Funktion herumspringen. Das ist z.B. in C++ trotzdem problematisch wegen RAII, aber ich sehe in BlitzMax keine technischen Probleme mit Goto.
Man darf es nicht übertreiben Very Happy

@funkheld: Ja das meinte ich mit "bauen", weil üblicherweise mehr dahinter ist, als nur Kompilieren (z.B. Assemblieren & Linken).
Edit: habe übrigens gerade bemerkt, dass mein Patch bzgl Goto nicht ausreichend ist, damit es im Strict-Mode funktioniert.

Edit2:
Hier ist der komplette notwendige Patch:
Code: [AUSKLAPPEN]
diff --git a/src/compiler/parser.cpp b/src/compiler/parser.cpp
index 7d15da6..2566277 100644
--- a/src/compiler/parser.cpp
+++ b/src/compiler/parser.cpp
@@ -1419,14 +1419,9 @@ void Parser::parseLabelStm(){
    if( strictMode ){
       while( cparse('\n') ){}
       switch( curr() ){
-      case T_FOR:case T_WHILE:case T_REPEAT:case T_DEFDATA:
-         break;
-      default:
-         fail( "Labels must appear before a loop or DefData statement" );
-      }
-      if( curr()!=T_DEFDATA ){
+      case T_FOR:case T_WHILE:case T_REPEAT:
          loopLabel=id;
-         return;
+         break;
       }
    }
    if( block->fun_block->labels.count(id) ) fail( "Duplicate label '%s'",id.c_str() );
--- a/src/compiler/stm.cpp
+++ b/src/compiler/stm.cpp
@@ -38,7 +38,6 @@ void LabelStm::eval( Block *b ){
 
 //******************** Goto ***********************
 void GotoStm::eval( Block *b ){
-   if( strictMode ) fail( "Goto cannot be used in strict mode" );
    FunBlock *f=b->fun_block;
    map<string,LabelStm*>::iterator it=f->labels.find( tolower(ident) );
    if( it==f->labels.end() ) fail( "Label '%s' not found",ident.c_str() );
 

funkheld

BeitragSo, Feb 25, 2018 14:27
Antworten mit Zitat
Benutzer-Profile anzeigen
--------------------------------------
...du kannst nur innerhalb der momentanen Funktion herumspringen
--------------------------------------

Innerhalb der Funktion geht es nicht.

Gruss

BladeRunner

Moderator

BeitragSo, Feb 25, 2018 14:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Goto ist schlicht aus Gründen der Abwärtskompatibilität enthalten und in BMax durch andere Konstrukte ersatzlos ersetzbar. Sobald Du Superstrict bist ist es schlicht nicht mehr im Sprachkatalog, und das ist gut so.
Es gibt keinen mir bekannten Anwendungsfall den man nicht ohne goto lösen könnte.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Jolinah

BeitragSo, Feb 25, 2018 15:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Das letzte Beispiel von Thunder liesse sich auch über ein anderes Konstrukt lösen Wink

Edit: Sorry habe erst jetzt gesehen, dass du Exceptions auch schon erwähntest. Aber meiner Meinung nach ist Try-Catch genau dafür gedacht. Versuche das hier, wenn es scheitert, reagiere so auf den Fehler.

BlitzMax: [AUSKLAPPEN]
Function openConfig:String[] ()
Local f:TStream = OpenFile("c:\config.txt")
If f = Null Then
Return Null
EndIf

Try
Local options:String[]

While Not Eof(f)
' datei parsen
If error Then
Throw "parsing error #1"
EndIf
' weiter parsen
If error2 Then
Throw "parsing error #2"
EndIf
Wend

CloseFile f
Return options
Catch exception:Object
CloseFile f
Return Null
End Try
EndFunction

Thunder

BeitragSo, Feb 25, 2018 16:13
Antworten mit Zitat
Benutzer-Profile anzeigen
@Jolinah: coole Lösung, ich dachte bei exceptions mehr daran, dass man sie aus der Funktion hinauswerfen würde. Sodass dann der Benutzer von OpenConfig eventuell eine abfangen muss.
Ich programmiere halt eher in Sprachen wo Exceptions nicht vorhanden oder selten explizit gebraucht werden.

@funkheld: Bei mir kompiliert deine Funktion. Es reicht wahrscheinlich wenn du meine zwei Beiträge nochmal aufmerksam liest. Da steht alles drinnen. Ich kann mir nicht vorstellen, dass dir jemand anderes dabei helfen wird, Goto zum laufen zu bringen Razz
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit

Jolinah

BeitragMo, Feb 26, 2018 20:30
Antworten mit Zitat
Benutzer-Profile anzeigen
@Thunder: Danke. Grunsätzlich hast du schon recht, Exceptions sollten eher nach aussen geworfen werden. So wird die Exception intern geschluckt und der Aufrufer bekommt Null zurück, ohne zu wissen woran es liegt.

In Sprachen wie C# hat man da noch etwas mehr Möglichkeiten:
Code: [AUSKLAPPEN]
try
{
    ...
}
finally
{
    stream.Close();
    stream.Dispose();
}


Das Finally wird in jedem Fall aufgerufen, egal ob eine Exception geworfen wird oder nicht. So kann man die Exceptions ruhig nach aussen werfen lassen.
 

sinjin

BeitragSo, Jul 01, 2018 2:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich finde "goto" in manchen Fällen auch sehr hilfreich...Wusstest du das ein JUMP in Assembler Gang und Gebe ist? Da würde keiner sagen, schlechter Code Very Happy Einfach aus dem Grund, weil es NICHT anders geht. Verstehe ich nicht, das man in Hochsprachen 10 Schleifen haben soll, als 1 Schleife mit einem Goto.

BladeRunner

Moderator

BeitragSo, Jul 01, 2018 11:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Weil es unübersichtlichen Code generiert, wenn man sich in Goto verrennt. Hochsprachen wurden ja grade geschaffen um einen sauberen, besser wartbaren Code zu schaffen, wohingegen Assembler halt exakt die direkten Möglichkeiten der Hardware abbildet. Aber auch in Assembler ziehe ich ein JSR einem JMP vor, weil ich damit funktionalitäten kapseln kann.
Das ist somit also Äpfel mit Birnen verglichen.
OOP und oder Prozeduraler Code haben sich ja grade wegen dieser Vorzüge durchgesetzt.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group