goto und Speicherfehler ...
-
Inspirit vom "Ist goto noch evil"-Thread im allgemeinen Programmierforum bin ich folgendes Gedankenkonstrukt durchgegangen:
int main() { /*Springe direkt in die Schleife ...*/ goto LABEL; { int a=0; while(a<10) /*Wurde, wenn zu LABEL gesprunden wird, überhaupt die Initialisierung **von a statt, oder ist die Variable so ohne Speicher?*/ LABEL: a++; } return 0; }
Meine Frage: Wenn man die Definition und Initialisierung von a weglässt und direkt in die Schleife springt, trickst man somit nicht den Stack aus und hinterlässt eine Variable ohne Speicheradresse? Würde mich mal interessieren.
-
Probier's doch aus. Du wirst feststellen, es ist nicht erlaubt.
Übrigens ist das Anlegen einer Variablen nicht wirklich etwas, was passiert. Das ist ein abstraktes Konzept der Programmiersprache, kein echter Maschinenbefehl. Wenn du selber Assemblercode einfügst, der zu LABEL springt, dann benutzt das Programm nachher ganz normal die Variable a. Du hast bloß die initialisierung übersprungen (mit bekannten Konsequenzen) und eventuell wurde auch der Stackpointer nicht gesetzt (der dürfte aber in 99.9% der Fälle schon am Anfang der Funktion richtig gesetzt werden), was dann schon unangenehmere Konsequenzen hatte.
-
SeppJ schrieb:
Probier's doch aus. Du wirst feststellen, es ist nicht erlaubt.
Für gewöhnlich vermeide ich
goto
, weil immer wieder gesagt wird, dass ese böse sei. Ich denke aber, es hat auch positive Seiten.SeppJ schrieb:
Übrigens ist das Anlegen einer Variablen nicht wirklich etwas, was passiert. Das ist ein abstraktes Konzept der Programmiersprache, kein echter Maschinenbefehl. Wenn du selber Assemblercode einfügst, der zu LABEL springt, dann benutzt das Programm nachher ganz normal die Variable a. Du hast bloß die initialisierung übersprungen (mit bekannten Konsequenzen) und eventuell wurde auch der Stackpointer nicht gesetzt (der dürfte aber in 99.9% der Fälle schon am Anfang der Funktion richtig gesetzt werden), was dann schon unangenehmere Konsequenzen hatte.
Danke für die Erklärung.
-
Glühbirne schrieb:
SeppJ schrieb:
Probier's doch aus. Du wirst feststellen, es ist nicht erlaubt.
Für gewöhnlich vermeide ich
goto
, weil immer wieder gesagt wird, dass ese böse sei. Ich denke aber, es hat auch positive Seiten.Nein, ich meine, probier doch einfach dein Programm aus!
-
Ausprobieren hilft da nicht; ein C-Compiler darf das durchaus akzeptieren. gcc 4.6 tut es und warnt auch erst mit -Wall. Der Grund dafür dürfte sein, dass so etwas in switches andauernd vorkommt.
Natürlich ist es undefiniert, die Variable, deren Deklaration übersprungen wurde, zu benutzen - was der Compiler daraus schlussendlich macht, kann dir niemand sagen.
Was goto angeht, es gibt in C-Kreisen eine Denkschule, die goto zur Fehlerbehandlung für gerechtfertigt hält (da wird dann eine Art kruder RAII-Nachbau betrieben), und zum Verlassen geschachtelter Schleifen sieht man es von Zeit zu Zeit. Ich halte von beidem nicht viel - in der Regel kriegt man das mit geschickter Refaktorisierung besser hin - aber in diesen Zusammenhängen ist es wohl vertretbar.
Grundsätzlich ist das Problem halt, dass goto, wenn man nicht sehr, sehr, sehr vorsichtig ist, den Code schneller verknotet als Alexander der Große ihn wieder lösen könnte. Wenn du einen Weg findest, die Übersichtlichkeit mit goto zu erhöhen, solltest du eine Dissertation darüber schreiben - die stünde auch über jedem Plagiatsverdacht, denn das hat vorher noch niemand geschafft.
-
seldon schrieb:
Wenn du einen Weg findest, die Übersichtlichkeit mit goto zu erhöhen, solltest du eine Dissertation darüber schreiben - die stünde auch über jedem Plagiatsverdacht, denn das hat vorher noch niemand geschafft.
Dann musst du mal meine Abhandlung über die neuen Sprachkonstrukte for, while und do lesen. Für C++ schlage ich auch noch etwas vor, dass sich Exception nennen wird. Ich hoffe die Standardkommissionen nehmen dies als übersichtlichen Ersatz für goto an.
-
seldon schrieb:
Grundsätzlich ist das Problem halt, dass goto, wenn man nicht sehr, sehr, sehr vorsichtig ist, den Code schneller verknotet als Alexander der Große ihn wieder lösen könnte. Wenn du einen Weg findest, die Übersichtlichkeit mit goto zu erhöhen, solltest du eine Dissertation darüber schreiben - die stünde auch über jedem Plagiatsverdacht, denn das hat vorher noch niemand geschafft.
Hmmm, das sollte ich wirklich, denn ich habe noch irgendwo ein Beispiel in C# rumfliegen, wo ich oft und vorsichtig mit
goto
gearbeitet habe (war, glaube ich, ein Parser, bei dem eine Schleife mit Abbruchbedingungen und dem ganzen Kram das ganze unleserlich gemacht hätte).
-
Ist wohl eine Grauzone der Compilerhersteller geblieben?
Borland CBuilder schluckt das Beispiel mit einer simplen Warnung 'unreachable code' macht aber dennoch jede gewünschte Deklaration mit Initialisierung, ohne in den Bereich zwischen goto label; und label: zu gelangen. Und was lernt uns das?Eigentlich nichts!