• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Ein goto zu einer bestimmten stelle

mmp5

Member
Also hab bis jetzt eigentlich richtig nur MAschienencode programiert:

will mir jetzt C LANGSAM angewöhnen:

mein Lehrer hat gesagtm dass es sowas wie ein

goto

gibt, wo er zu einer bestimmten stelle im Programm Springt:

vielleicht so (z.B.)?

...
...
goto 1
...
...
...
...
1:


er soll von goto 1 auf 1: springen und alle schritte dazwischen ausseracht lassen;

wie sieht die syntax genau aus. Bitte an nem Beispiel wenn ihr habt ...

THX im voraus
 

TeXpert

Guru
taki schrieb:
so pauschal würde ich das nicht stehen lassen....

es gibt Situationen bei denen IMHO ein goto akzeptabel ist, Beispiel in einer Funktion die viele Fehlerquellen hat und bei der am Ende aufgeräumt werden muss (Devices freigeben etc.) hier kann ein goto sehr helfen... zumindest kann man damit tief verschachtelte if-then-else Konstrukte verhinden.

Aber man sollte damit _sehr_ bewußt umgehen :)

Kerninghan & Ritchie schrieb:
C verfügt auch über eine beliebig zu mißbrauchende goto-Anweisung und Marken zu denen gesprungen werden kann. Formal ist goto niemals notwendig und man kann fast immer licht ohne goto-Anweisungen auskommen

[/quote]
 

taki

Advanced Hacker
Es gibt eigentlich immer eine Alternative, auch ohne übermaßig verschachtelte if-Konstrukte, mindestens in allen Sprachen, die Funktionen kennen. GOTOs akzeptiere ich eigentlich nur in den vielen Cobol-Modulen, die unser Team in Pflege hat - aber nur, bis die alte Garde abtritt...
 

TeXpert

Guru
taki schrieb:
Es gibt eigentlich immer eine Alternative, auch ohne übermaßig verschachtelte if-Konstrukte, mindestens in allen Sprachen, die Funktionen kennen.

nein, dass passt so auch nicht, mit Funktionen hast Du u.u. andere Probleme..

Code-Sample:

Code:
init device_a
if !success goto error
init device_b
if !success goto error
init device_c
if !success goto error
do something

error:
if device_c close it
if device_b close it
if device_a close it
return
wenn hier jetzt eine Funktionale abhängig der Reihenfolge gegeben ist, musst Du bei Programmierung ohne goto wieder geschachtelte if-then-else Konstrukte aufbauen oder aber viele Aussprungpunkte aus einer Funktion in Kauf nehmen...
Code:
init device_a
if !success closeall && return;
init device_b
if !success closeall && return;
init device_c
if !success closeall && return;

do_something
...
closeall && return;


function closeall
if device_c close it
if device_b close it
if device_a close it
[/code]
 

oc2pus

Ultimate Guru
taki schrieb:

Go To Statement Considered Harmful
Edsger W. Dijkstra
http://www.acm.org/classics/oct95/

http://www.fortran.com/fortran/come_from.html
Nearly six years after publication of Dijkstra's now-famous letter, [1] the subject of GOTO-less programming still stirs considerable controversy. Dijkstra and his supporters claim that the GOTO statement leads to difficulty in debugging, modifying, understanding and proving programs. GOTO advocates argues that this statement, used correctly, need not lead to problems, and that it provides a natural straightforward solution to common programming procedures.

und natürlich:
http://en.wikipedia.org/wiki/Control_flow (Kapitel Goto)

c020.gif
 

taki

Advanced Hacker
TeXpert schrieb:
taki schrieb:
Es gibt eigentlich immer eine Alternative, auch ohne übermaßig verschachtelte if-Konstrukte, mindestens in allen Sprachen, die Funktionen kennen.

nein, dass passt so auch nicht, mit Funktionen hast Du u.u. andere Probleme..

Code-Sample:

Code:
init device_a
if !success goto error
init device_b
if !success goto error
init device_c
if !success goto error
do something

error:
if device_c close it
if device_b close it
if device_a close it
return
wenn hier jetzt eine Funktionale abhängig der Reihenfolge gegeben ist, musst Du bei Programmierung ohne goto wieder geschachtelte if-then-else Konstrukte aufbauen oder aber viele Aussprungpunkte aus einer Funktion in Kauf nehmen...
Code:
init device_a
if !success closeall && return;
init device_b
if !success closeall && return;
init device_c
if !success closeall && return;

do_something
...
closeall && return;


function closeall
if device_c close it
if device_b close it
if device_a close it
[/code]

Warum aus closeall wieder zurückkehren? Ein GOTO wird i.d.R. nur für den Querausstieg anerkannt. Warum nicht eine explizite Funktion, die nur dazu existiert, einen geordneten Querausstieg zu haben? Ich habe hier etwa 50 Cobolmodule vorliegen, die GOTOS enthalten. Alle gehen zu "XY-FEHLERAUSGANG-9999" Sieht häßlich aus. Meine eigenen springen immer die selbe Section an, die mit EXIT-PROGRAM. endet. In C, C++, bash u.s.w. stünde da bei mir dann exit();

Fehlerausgänge können auch erst mal einen Umweg über Funktionen machen, die den Fehler selbst behandeln. Aber am Ende gehen sie alle über die gleiche Funktion zum exit(). So gibt es auch bei mir nur einen einzigen definierten Endpunkt. Einen GOTO habe ich dafür nie gebraucht. Ich darf ihn nur leider (noch) nicht aus den vielen alten Sourcen entfernen.

Oc2pus schrieb:
Go To Statement Considered Harmful
Edsger W. Dijkstra
http://www.acm.org/classics/oct95/

Danke, Toni. Den kannte ich, hat mich auch stark beeinflusst.
 

TeXpert

Guru
ich verteidige Gotos nicht bis zum letzen ;) aber es gibt Situationen in denen es IMHO Akzeptabel ist...

aber ich gebe auch zu, dass ich mich jetzt spontan auch nur an ein Projekt erinnere wo sich das ganze Team für gotos in so einer low-level-Initialisierung ausgesprochen hat :) ich müsste jetzt auch in den alten Dokumenten wühlen um die genaue Situation zu finden ... wenn ich mich richtig erinnere war es so ähnlich wie mein Beispiel aber mit unterschiedlichen Aussprungzielen (unterschiedliche goto-Targets)... es wäre möglich gewesen, das mit Funktionen zu machen, dann hätten wir aber

a/ frühere Aufräumfunktionen von späteren Zuständen aufrufen müssen (mehrfache Stacktiefe == Performance Verlust)
b/ oder Code mehrfach schreiben müssen...

unter dem Strich kam dabei unter Verwendung von Gotos ein
1. wartbarer Code (für diese eine Situation)
2. ein schneller Code raus (ein profiler hilft manchmal auch den objektiv schlechteren Code zu akzeptieren...)

und das sind Situationen in denen Gefahren auch mal dokumentiert und akzeptiert werden können ;)


EDIT: ein kleiner nachtrag: http://www.wikiservice.at/dse/wiki.cgi?GoToJaOderNein
 

regexer

Advanced Hacker
TeXpert schrieb:
ich verteidige Gotos nicht bis zum letzen ;) aber es gibt Situationen in denen es IMHO Akzeptabel ist...
Ich gehe diesem Streit gerne wiefolgt aus dem Weg:
Sind nicht Befehle wie "break" zum Schleifen-Verlassen, oder auch "escape top", oder "last", oder "next" oder wie sie alle heißen nicht auch versteckte "Gotos"?
 

TeXpert

Guru
notoxp schrieb:
TeXpert schrieb:
ich verteidige Gotos nicht bis zum letzen ;) aber es gibt Situationen in denen es IMHO Akzeptabel ist...
Ich gehe diesem Streit gerne wiefolgt aus dem Weg:
Sind nicht Befehle wie "break" zum Schleifen-Verlassen, oder auch "escape top", oder "last", oder "next" oder wie sie alle heißen nicht auch versteckte "Gotos"?
absolut :) allein aus diesem Grund ist die missionarische Ablehnung von gotos flashc ....

BTW: mit ein paar Coding-Guidelines zu Gotos kann man das sehr entspannt sehen, ich springe mit einem Goto niemals im Quelltext zurück (das ist eine typische Schleifen-aufgabe) und wenn es sich um erhebliche Einsparungen handelt die ich mir damit erkaufe (OK, dann ist meißt der Kommentar fast so lang wie der gesparte Code aber seis drum...
 

panamajo

Guru
notoxp schrieb:
Sind nicht Befehle wie "break" zum Schleifen-Verlassen, oder auch "escape top", oder "last", oder "next" oder wie sie alle heißen nicht auch versteckte "Gotos"?
Nein. Die genannten Konstrukte implementieren (zumindest implizit) einen bedingten Sprung, goto einen unbedingten Sprung. Und darauf kann man immer verzichten.
 

TeXpert

Guru
panamajo schrieb:
notoxp schrieb:
Sind nicht Befehle wie "break" zum Schleifen-Verlassen, oder auch "escape top", oder "last", oder "next" oder wie sie alle heißen nicht auch versteckte "Gotos"?
Nein. Die genannten Konstrukte implementieren (zumindest implizit) einen bedingten Sprung, goto einen unbedingten Sprung. Und darauf kann man immer verzichten.

nein. machen wir ein kleines Beispiel:

Version 1:
Code:
#include <stdio.h>

int main() {

        int i,j;
        printf("Zahl: ");
        scanf("%d", &i);
        for(j = 0; j<i; j++) {
                if (j > 5) goto thelabel;
                printf("in the loop\n");
        }

        thelabel:
        ;
}
und die analoge Form mit break:
Code:
#include <stdio.h>

int main() {

        int i,j;
        printf("Zahl: ");
        scanf("%d", &i);
        for(j = 0; j<i; j++) {
                if (j > 5) break;
                printf("in the loop\n");
        }

        thelabel:
        ;
}

beide Versionen unterscheiden sich nur im goto und im break, der generierte Maschinen-Code ist identisch (wie Du Dich gerne mit einem gcc -S foo.c überzeugen kannst.

de facto machen ein break oder continue und ein goto genau das gleiche, es kommt nur auf die gesamte Sematik der Funktion an.

Du kannst natürlich bei einer verschachtelten Schleifengeschichte in jedem Schleifenkörper ein if (FOO) break; machen oder direkt ein goto ENDOFLOOPBLOCK, das 2. ist IMHO deutlich besser zu lesen...
 

andreasw

Member
Man hat ja eben Schleifen Statements usw hinzugefügt, damit man sich keine Gedanken mehr machen muss, ob ein Quellcode strukturiert programmiert ist.

Natürlich kannst du mit GOTO auch absolut strukturiert programmieren, nur musst du dann eben aufpassen.

Jede Schleife kannst du ja mit GOTO nachbilden.

Ich verwende Goto auch nicht ;)

mfg

Andy
 

panamajo

Guru
TeXpert schrieb:
de facto machen ein break oder continue und ein goto genau das gleiche, es kommt nur auf die gesamte Sematik der Funktion an.
Ok, ich habe break nur im Zusammenhang mit switch() beachtet, nicht diese break & continue Grütze bzgl. Schleifen.
Für Schleifen kann man tatsächlich Fälle konstruieren wo der Code unter der Verwendung von break besser lesbar ist und näher an der Semantik des implementierten Algorithmus ist. Kann, muss aber nicht - mit einer geringen Anzahl break und continue kann man eine triviale Schleife zur Debug-Herausforderung aufpumpen...
 

TeXpert

Guru
panamajo schrieb:
Ok, ich habe break nur im Zusammenhang mit switch() beachtet, nicht diese break & continue Grütze bzgl. Schleifen.
da gilt btw. das gleiche :)

Code:
#include <stdio.h>

int main() {

        int i;
        printf("Zahl: ");
        scanf("%d", &i);
        switch (i) {
                case 1:
                        printf("eins");
                        break;
                case 2:
                        printf("zwei");
                        break;
        }
        thelabel:
        ;
}
und
Code:
#include <stdio.h>

int main() {

        int i;
        printf("Zahl: ");
        scanf("%d", &i);
        switch (i) {
                case 1:
                        printf("eins");
                        goto thelabel;
                case 2:
                        printf("zwei");
                        goto thelabel;
        }
        thelabel:
        ;
}
liefern auch die gleichen Maschinenbefehle ;) (wenn Du es testest, kann es sein, dass sich die jmp-Label unterscheiden, aber die reinen Mnemonics sind identisch.

Kann, muss aber nicht
absolute Zustimmung :) genau darauf will ich ja raus, es sind Situationen möglich, in denen ein goto angebracht sein kann (es sei denn man stellt sich auf den Standpunkt function follows form ;))
 

alley_cat

Newbie
Ich denke, wenn man C oder C++ oder sonst irgendeine prozedurale Programmiersprache waehlt, gehoert ein GOTO stilistisch nicht in den Quelltext. Im uebrigen wird das begruendet, um die Uebersicht bei unbedingten Spruengen nicht zu verlieren.

Wenn jemand haeufig programmiert, faellt ein GOTO im Konstrukt sofort ins Auge, anstatt zum Beispiel die switch-case-break Anweisung.

GOTO war definitiv zu BASIC-Zeiten in, weil man dort noch Zeilennummern fuer Anweisungen nutzte. Ein Label in einer Prozedur bzw. einer Funktion zu setzen ist ein sehr schlechter Programmierstil.

Alte Informatikerweisheit :)
 

framp

Moderator
Teammitglied
Vor lauter pros und cons zu Labels wurde die eigentliche Frage nicht beantwortet:

@mmp5
Ich habe auch keine Beispiele, da ich auch keine Labels benutze :roll: . Allerdings habe ich die C Bibel im Schrank stehen und da steht:

jump statement:
goto identifier ;

und

labeled-statement:
identifier : statement

also

Code:
if ( ...) {
   ...
   goto sprung;
   ...
}


sprung: ...
 

framp

Moderator
Teammitglied
Ich kenne uebrigens noch etwas schlimmeres als ein goto: Eine Exception - auch als goto everywhere bezeichnet :lol:
 

SchodMC

Newbie
Wenn ich mich mal einmischen darf:

Seit ich code jetzt schon seit ca. 15 Jahren. Angefangen mit GW-Basic bis nun hin zu C/C++. Seit ich von GW-Basic weg bin verwende ich kein Goto mehr und komme recht gut damit klar. Es gibt mehrere Wege - wenn man das Beispiel mit der Initialisierungs-Funktion aufgreifen darf:
Code:
// Init 3 devices...
if (!InitDev1() || !InitDev2() || !InitDev3())
{
    CleanUpAll();
    PrintErrMsg();
    return;
}
Da der Compiler beim ersten nicht erfolgreichen Initialisieren in den If-Block hineinspringt ohne die nachfolgenden InitDevX() Funktionen aufzurufen, ist das soweit kein problem und goto wird nicht verwendet.

Eine andere und Zeitgemäßere Version wäre eben mit exceptions:
Code:
try
{
    // Die init-funktionen werfen im Fehlerfall eine Exception...
    InitDev1();
    InitDev2();
    InitDev3();
    InitDev1();
}
catch (...)   // Man kann noch einen Speziellen Exception-Typ definieren
{
    CleanUpAll();
    PrintErrMsg();
    return;
}
Exceptions sind eine feine Sache und gar nicht kompiziert!

In ganz seltenen Situationen mag goto ggf. noch Sinn machen, aber ich würde mal behaupten das in 98% der Fälle sich ein Problem auch ohne goto lösen lässt. Goto selber kann leicht dazu führen, dass der Code unübersichtlich wird.

Das Argument, was der Compiler für einen Code erzeugt, ist irrelevant, da es für mich als Entwickler wichtiger ist, einen übersichtlichen und verständlichen Code zu haben.

Ich würde auf jeden Fall empfehlen, wenn man schon goto verwendet, auch in einem Kommentar eine Begründung dafür abzugeben. Ist immer hilfreich für spätere Arbeiten.
 
Oben