Forum: Compiler & IDEs goto-Label an Funktion übergeben?


von Paul H. (powl)


Lesenswert?

Hi,

sagtmal... kann man in C ein goto-Label an eine Funktion übergeben damit 
man aus der Funktion heraus an eine beliebige, vorher definierte Stelle 
hinspringen kann?

so a la
1
void superklassefunktion(label sprungadresse)
2
{
3
  tu_irgendwas_ganz_ganz_tolles();
4
  goto sprungadresse;
5
}
6
7
// ....
8
9
hier_hin_springen_bitte:
10
  tu_was();
11
  tu_nochwas();
12
13
  tu_irgendwas_ganz_ganz_tolles(hier_hin_springen_bitte);


Und bitte keine Moralpredigt über die Verwendung von goto, ich setze es 
verantworungsbewusst ein :)

lg, PoWl

von Εrnst B. (ernst)


Lesenswert?

Jain.
siehe setjmp/longjmp

normale Labels gelten nur innerhalb einer Funktion.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Paul Hamacher schrieb:
> Und bitte keine Moralpredigt über die Verwendung von goto, ich setze es
> verantworungsbewusst ein :)

Ok - dann halt nicht ;)

got ist nur innerhalb einer Funktion zulässig (sagen mein Compiler
und dessen Handbuch). Dann müßtest Du auch erst mal die Adresse des
goto herausbekommen ... so etwas wie foo( &goto) dürfte kaum ... :-)

von Mark B. (markbrandis)


Lesenswert?

Joachim Drechsel schrieb:
> so etwas wie foo( &goto) dürfte kaum ... :-)

So schaut's aus, der Adress-Operator kann Adressen von Variablen und 
Strukturen bestimmen, aber nicht die von Funktionen.

Hm, man könnte vielleicht versuchen eine Struktur anzulegen, die als 
Member einen Funktionspointer enthält, von der struct die Adresse 
bestimmen und dann damit Unsinn treiben... aber will man das :-)

Paul Hamacher schrieb:
> Und bitte keine Moralpredigt über die Verwendung von goto, ich setze es
> verantworungsbewusst ein :)

Ja gibt's denn sowas? ;)

Der Wikipedia-Artikel über setjmp und longjmp ist übrigens 
aufschlussreich:
http://en.wikipedia.org/wiki/Setjmp.h

von Peter II (Gast)


Lesenswert?

Mark Brandis schrieb:
> So schaut's aus, der Adress-Operator kann Adressen von Variablen und
> Strukturen bestimmen, aber nicht die von Funktionen.

warum denn nicht, wie sollte sonst funktionzeiger funktionieren?

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Wie bekommt man die Adresse des gotos heraus (danach hatte er ja 
gefragt) ?

von Kan a. (Firma: Basta) (kanasta)


Lesenswert?

Über den Sinn deines Vorhabens könnte man sicher viel diskutieren, aber 
möglich ist es auf jeden Fall. Du kannst als Datentyp (void *) nehmen.

von Klaus W. (mfgkw)


Lesenswert?

Aber auch damit kann man nur sinnvoll innerhalb eine Funktion springen 
(und auch da nur bedingt), aber nicht in f1() ein Label merken, an f2() 
übergeben und aus f2() an das Label in f1() springen - das geht nicht 
gut (auch wenn es zufällig mal so aussehen mag).

von Mark B. (markbrandis)


Lesenswert?

Peter II schrieb:
> warum denn nicht, wie sollte sonst funktionzeiger funktionieren?

Hm, tatsächlich kann man in dem nachfolgenden Beispiel den 
Adressoperator vor das add; schreiben. Ich kannte es aber immer nur 
ohne. Wieder was gelernt.
1
int add(int a, int b)
2
{
3
  return a + b;
4
}
5
6
int (*f) (int, int);
7
8
// in main()
9
f = add;
10
(*f)(3,2);

von (prx) A. K. (prx)


Lesenswert?

Mark Brandis schrieb:

Geht auch einfacher:
1
f(3,2);

von Klaus W. (mfgkw)


Lesenswert?

> Hm, tatsächlich kann man in dem nachfolgenden Beispiel den
> Adressoperator vor das add; schreiben. Ich kannte es aber immer nur
> ohne. Wieder was gelernt.

Bei K&R-C war das & nötig, später konnte es als Erleichterung 
weggelassen werden.
Mit einem Funktionsnamen kann man ja eh nur entweder mit () die Funktion 
aufrufen, oder ihre Adresse bilden; insofern ist das & überflüssig, weil 
es ohne die () nur um die Adresse gehen kann.

von (prx) A. K. (prx)


Lesenswert?

Klaus Wachtler schrieb:

> Bei K&R-C war das & nötig, später konnte es als Erleichterung
> weggelassen werden.

Ich habs andersrum in Erinnerung. Das & wurde später für jene 
hinzugefügt, die sonst konfus wurden.

Der Systematik halber gehören zusammen:
  f = &add; (*f)(3,2)
oder alternativ die klassische Variante:
  f = add; f(3,2)

von Klaus W. (mfgkw)


Lesenswert?

A. K. schrieb:
> Ich habs andersrum in Erinnerung. Das & wurde später für jene
> hinzugefügt, die sonst konfus wurden.

Tja, wir mit K&R-Anfängen kommen langsam in das senile Alter.
 :-)

>
> Der Systematik halber gehören zusammen:
>   f = &add; (f*)(3,2)

Nicht eher "*f" statt "f*"?

PS: hast du gerade noch die Kurve gekriegt!

von (prx) A. K. (prx)


Lesenswert?

Die (ursprüngliche) innere Logik: Der Name einer Funktion ist deren 
Adresse, der Operator () ist die Dereferenzierung des Zeigers auf eine 
Funktion.

Deshalb ist
  add(2,3)
und
  f(2,3)
im Grunde der gleiche Vorgang: links die Adresse einer Funktion, rechts 
deren Dereferenzierung. Im einen Fall ist die Adresse konstant, im 
anderen Fall nicht. Da aber nicht jeder Programmierer in Grammatiken 
denkt, hat man später auch &/* zugelassen.

von Ralf G. (ralg)


Lesenswert?

Paul Hamacher schrieb:
> Und bitte keine Moralpredigt über die Verwendung von goto, ich setze es
> verantworungsbewusst ein :)

Darf ich trotzdem mal nach einer sinnvollen Anwendung für diese 
Konstruktion fragen? Vor allem: Wie kommt man mit dem 'Stack-Salat' 
klar?

von Karl H. (kbuchegg)


Lesenswert?

Ralf G. schrieb:
> Paul Hamacher schrieb:
>> Und bitte keine Moralpredigt über die Verwendung von goto, ich setze es
>> verantworungsbewusst ein :)
>
> Darf ich trotzdem mal nach einer sinnvollen Anwendung für diese
> Konstruktion fragen?

Das ist leicht:
Eine Methode um sich selbst möglichst kryptisch und unleserlich 
möglichst tief ins eigene Knie zu schiessen.

von Ralf G. (ralg)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Das ist leicht:
> Eine Methode um sich selbst möglichst kryptisch und unleserlich
> möglichst tief ins eigene Knie zu schiessen.

'Kryptisch und unleserlich' - das ist der 1.Teil ...

von Mark B. (markbrandis)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Eine Methode um sich selbst möglichst kryptisch und unleserlich
> möglichst tief ins eigene Knie zu schiessen.

:-)))

von Der E. (rogie)


Lesenswert?

Ralf G. schrieb:
> 'Kryptisch und unleserlich' - das ist der 1.Teil ...

Und der zweite?

Durch wildes hin und herspringen in und aus Funktionen jeden total 
verwirren (auch den Prozessor g)

von Paul H. (powl)


Lesenswert?

Das mit dem Stack-Salat ist in der Tat ein Problem, das hab ich garnicht 
bedacht. Ideal wäre es, wenn er direkt NACH der Funktion an die 
angegebene Adresse springen würde.

Einsatzzweck: Es geht um eine Eingabemaske auf einem LCD. Man kann 
mehrere Zahlen eingeben. Die Zahleneingabe erfolgt indem das Programm in 
eine Funktion hineinspringt, welche die Tastatureingaben verarbeitet und 
an vorgegebener Stelle auf dem LCD ausgibt. Sobald die Zahl eingegeben 
wurde ist die Funktion zuende und es geht weiter im Code. Wenn man 
jedoch in der Eingabemaske einen bereits eingegebenen Wert ändern möchte 
muss man im Programm zurückspringen können, und zwar immer einen 
Eingabeschritt zurück. Da eignet sich meines Erachtens nur goto für, 
denn eine Schleife kann immer nur in eine Richtung springen. Die Idee, 
die Sprungadresse an die Zahleneingabefunktion mit zu übergeben könnte 
mir helfen, aus der Funktion heraus direkt eine Eingabe 
zurückzuspringen. Aber ja, da ist das Stack-Problem, da er sich ja dann 
nur noch tiefer in eine Funktion nach der anderen verschachtelt.

Edit:
Ach jetzt schimpft nicht so über goto! ;) Manchmal hat man eben keine 
Lust jedes mal eine Merker-Variable mitzuschleppen wenn man an 
geeigneter Stelle eine Sprungfunktion einsetzen kann. Spaghetticode ist 
nix gut aber eine lange Nudel mit nem kleinen Knoten drin ist noch lange 
keine Spaghetti.

von Der E. (rogie)


Lesenswert?

Paul Hamacher schrieb:
> Da eignet sich meines Erachtens nur goto für,


Aber nur deines Erachtens.
Mit einer State machine z.B. kann man das ganz ohne gotos machen.

von Stephan (Gast)


Lesenswert?

Ralf G. schrieb:
> Paul Hamacher schrieb:
>> Und bitte keine Moralpredigt über die Verwendung von goto, ich setze es
>> verantworungsbewusst ein :)
>
> Darf ich trotzdem mal nach einer sinnvollen Anwendung für diese
> Konstruktion fragen? Vor allem: Wie kommt man mit dem 'Stack-Salat'
> klar?

Darüber ist er sich wahrscheinlich gar nicht im klaren.

von Peter II (Gast)


Lesenswert?

> Einsatzzweck: Es geht um eine Eingabemaske auf einem LCD. Man kann
> mehrere Zahlen eingeben.
dafür willst du gotos verwenden?

ist es nicht viel einfacher eine sich in einer Variabel sich die Zahl zu 
merken die gerade geändert wird?

int Ziffer = 1
while( editmod = 1 ) {
  if ( rechts && Ziffer > 1 ) {
      ZIffer--;
  }

  if ( links && Ziffer < x ) {
      ZIffer++;
  }

  lese_ziffer( Ziffer );
}

von Ralf G. (ralg)


Lesenswert?

1
while (sonstwas)
2
{
3
 switch (pos)
4
 {
5
  case 0:
6
   // diverse Tests
7
   // Funktionsaufrufe
8
   break;
9
  case 1:
10
   // diverse Tests
11
   // Funktionsaufrufe
12
   break;
13
  case 2:
14
   // diverse Tests
15
   // Funktionsaufrufe
16
   break;
17
18
// ...
19
20
  default:
21
   // diverse Tests
22
   // Funktionsaufrufe
23
   break;
24
 }
25
}
Macht man da nicht sowas? 'pos' kann man zu jeder Zeit 
de-/inkrementieren oder einen neuen Wert zuweisen und sich so durch ein 
Menü hangeln.

von Karl H. (kbuchegg)


Lesenswert?

Ralf G. schrieb:

> Macht man da nicht sowas?

Kann man.
Man kann aber auch eine schöne Struktur erfinden, die ein Eingabefeld 
beschreibt und dann für eine Eingabeseite ein Array aus derartigen 
Objekten machen.
Das Vorwärts/Rückwärtsspringen durch die Eingabefelder ist dann nichts 
anderes als das Inkrementieren bzw. Dekrementieren des aktuellen Index, 
welcher darüber entscheidet, welches dieser Beschreibungsobjekte an die 
Funktion übergeben wird, welche die Benutzeringaben überwacht und die 
Wertemanipulation vornimmt. Kommt die Funktion zurück, gibt sie Auskunft 
darüber, wie der Benutzer entschieden hat: will er zum vorhergehenden 
Eingabefeld, zum nachfolgenden oder ist er mit der Maske überhaupt 
fertig.

Das ganze ist Codemässig ziemlich banal, das eigentliche Aussehen der 
Maske mit all ihren Eingabefeldern findet sich an einer Stelle im Code 
wieder und besteht einzig aus einer Zusammenfassung der Daten, die die 
Maske ausmachen.

Und das beste daran. Eine weitere Eingabemaske ist einfach nur ein 
weiteres Array, in dem der Aufbau der Maske beschrieben ist :-)


Es gibt Fälle, in denen ein goto tatsächlich eine gute Lösung ist. Mir 
ist nur in 28 Jahren kein einziger davon untergekommen :-)
(Um der Wahrheit genüge zu tun. Ich hab einmal einen goto benutzt. Muss 
so 15 Jahre her sein. Aber selbst den haben wir dann nach ein paar 
Jahren entfernt und durch etwas besseres ersetzt)

von Ralf G. (ralg)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Man kann aber auch eine schöne Struktur erfinden, die ein Eingabefeld
> beschreibt und dann für eine Eingabeseite ein Array aus derartigen
> Objekten machen.

Erstmal weg vom 'goto'! ;-)

von mips (Gast)


Lesenswert?

Paul Hamacher schrieb:
> Da eignet sich meines Erachtens nur goto für

Ach du bist der, für den die ganzen Warnungen geschrieben wurden! GoTo 
kann selten wirklich sinnvoll eingesetzt werden. Und deine 
Umsetzungsidee ist ehrlich gesagt eine der schlechtesten Möglichkeiten 
es zu verwenden von denen ich je gehört habe.
Auf jeden Fall nicht, so wie du denkst, eine gute Idee.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> Klaus Wachtler schrieb:
>
>> Bei K&R-C war das & nötig, später konnte es als Erleichterung
>> weggelassen werden.
>
> Ich habs andersrum in Erinnerung. Das & wurde später für jene
> hinzugefügt, die sonst konfus wurden.

War mir auch nicht so klar, stimmt aber offenbar.  Den "Ur-K&R"
(der eigentlich nur ein "R" ist) gibt's auf Dennis Ritchie's Seite
bei AT&T:

http://cm.bell-labs.com/cm/cs/who/dmr/cman.pdf

Da steht eindeutig, dass & nur auf Objekte anzuwenden ist, und
dass die Adresse einer Funktion automatisch dann gebildet wird,
wenn ein Funktionsname ohne die runden Klammern für deren Aufruf
benutzt wird.

Karl Heinz Buchegger schrieb:
> Es gibt Fälle, in denen ein goto tatsächlich eine gute Lösung ist. Mir
> ist nur in 28 Jahren kein einziger davon untergekommen :-)

Für klassisches "goto": vorzeitiges Rausspringen aus einer Funktion,
die sonst durch stark verschachtelte if-Anweisungen extrem unüber-
sichtlich würde.  Natürlich nur dann, wenn es ein einfaches "return"
(das ja ein verkapptes "goto" ist) nicht auch tun würde, weil
bswp. noch per malloc() allozierte Daten vorher zu beräumen sind.

Für setjmp/longjmp: Fehlerbehandlung; letztlich lassen sich C++-
Exceptions damit implementieren (im GCC-Jargon "sjlj" genannt),
und etwas Vergleichbares könnte man natürlich genauso für plain C
aufsetzen.

von (prx) A. K. (prx)


Lesenswert?

Klaus Wachtler schrieb:

> Nicht eher "*f" statt "f*"?
> PS: hast du gerade noch die Kurve gekriegt!

Wär freilich besser gewesen, C hätte diese Kurve nicht gekriegt. Mit der 
Dereferenzierung als Präfixoperator hängt der ganze Wirrwar schwer 
verständlicher Typdefinitionen zusammen. IIRC wollten sie es zunächst 
auch als Postfixoperator implementieren, merkten aber, dass a*-b dann 
zweideutig ist.

von Ralf G. (ralg)


Lesenswert?

Jörg Wunsch schrieb:
> Für klassisches "goto": vorzeitiges Rausspringen aus einer Funktion,
> die sonst durch stark verschachtelte if-Anweisungen extrem unüber-
> sichtlich würde.  Natürlich nur dann, wenn es ein einfaches "return"
> (das ja ein verkapptes "goto" ist) nicht auch tun würde, weil
> bswp. noch per malloc() allozierte Daten vorher zu beräumen sind.

Und die eigentliche Rücksprungadresse der Funktion auf dem Stack?

Diese 'Bastel'-Exeptions, könnte man die nicht auch so anwenden:
1
// 'try'
2
switch(x)
3
{
4
 default:
5
// Code
6
// ...
7
// noch mehr Code
8
// ...
9
// hier Code für 'was schiefgegangen'
10
// Fehlernummer setzen
11
  break;
12
// wieder Code
13
// ...
14
  break;
15
}
16
17
// 'catch'
18
 if (Fehler)
19
 {
20
// ...
21
 }
22
// schön aufräumen!
23
// ...
24
 return Fehler;
25
}
Ich hoffe, so ein Mehrfach-'break' geht genauso, wie Mehrfach-'return'.

von Stefan E. (sternst)


Lesenswert?

Ralf G. schrieb:
> Und die eigentliche Rücksprungadresse der Funktion auf dem Stack?

Was soll damit sein?
Jörg meint einen Sprung innerhalb der Funktion. So etwas:
1
void func (void) {
2
3
  ...
4
  // ganz
5
    // tief
6
      // verschachtelter
7
         // Code
8
           if (fehler)
9
             goto exit;
10
  ...
11
12
  exit:
13
    // Aufräumen
14
    close(...
15
    free(...
16
}

von (prx) A. K. (prx)


Lesenswert?

Jörg Wunsch schrieb:

> War mir auch nicht so klar, stimmt aber offenbar.  Den "Ur-K&R"
> (der eigentlich nur ein "R" ist) gibt's auf Dennis Ritchie's Seite
> bei AT&T:

Thx. Das ist noch die Version mit a =+ 1 statt a += 1.

Besonders gut gefällt mir dieser Satz: "In PDP-11 C none of this 
nonsense is necessary and the extern specifier is ignored in external 
definitions." Den Sachverhalt kannte ich schon, aber noch nie schön 
formuliert. Heute geht es ja meist nur auf die unsinnige Weise. ;-)

von Ralf G. (ralg)


Lesenswert?

Stefan Ernst schrieb:
> Was soll damit sein?
> Jörg meint einen Sprung innerhalb der Funktion. So etwas:
> ... ... ...

Das ist ja ein Sprung ans Ende. Nicht aus der Funktion raus!

Jörg Wunsch schrieb:
> Für klassisches "goto": vorzeitiges Rausspringen aus einer Funktion,

von Stefan E. (sternst)


Lesenswert?

Ralf G. schrieb:
> Das ist ja ein Sprung ans Ende. Nicht aus der Funktion raus!
>
> Jörg Wunsch schrieb:
>> Für klassisches "goto": vorzeitiges Rausspringen aus einer Funktion,

Es ist aber genau das, was Jörg meinte. Ein Sprung ans Ende der 
Funktion, um sie vorzeitig zu verlassen. Das, was du angenommen hast 
(ein goto aus der Funktion raus), existiert ja auch gar nicht.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

In GNU-C kann man Adressen von Labels nehmen und goto indirekt 
verwenden:
1
int weird_goto (unsigned x)
2
{
3
    static void **labels[] = { &&a, &&b, &&c };
4
5
    if (x >= sizeof (labels) / sizeof (labels[0]))
6
        return -1;
7
8
    goto *labels[x];
9
10
    a:  return 1;
11
    b:  return 2;
12
    c:  return 0;
13
}
Ob computed goto sinnvoll ist — etwa in auto-generiertem Code — sei 
dahingestellt. goto selbst ist in auto-generiertem Code jedenfalls 
häufiger anzutreffen als in handgeschriebenem. GCC zum Beispiel 
verwendet goto ausgiebig, etwa in insn-recog.c.

Solche Label-Adressen sind nicht sinnvoll an Funktionen zu übergeben, 
auch nicht wenn diese innerhalb von weird_goto verwendet werden.

Auf nonlocal goto aka. setjmp/longjmp um z.B. Ausnahmen nachzubilden 
wurde oben bereits hingewiesen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann L. schrieb:
> Ob computed goto sinnvoll ist — etwa in auto-generiertem Code — sei
> dahingestellt.

Computed goto braucht man für ordentliches FORTRAN-Feeling. :-)

Stefan Ernst schrieb:
>> Das ist ja ein Sprung ans Ende. Nicht aus der Funktion raus!

> Es ist aber genau das, was Jörg meinte.

Ja, sorry, wenn das beim mir nicht eindeutig klang.  Genau so meinte
ich es, wie Stefan das oben am Beispiel demonstriert hat.  Das halte
ich für eine der wenigen Anwendungen, bei denen ein paar gotos für
mehr Klarheit sorgen können, als wenn man diverse if-Anweisung immer
tiefer schachteln würde.

Von Donald E. Knuth gibt's ja auch einen Artikel "Structured
Programming with GOTO".

von Peter D. (peda)


Lesenswert?

Mit setjmp/longjmp kann man beim AVR-GCC sogar das bei Anfängern 
allseits so beliebte Springen aus einem Interrupt machen.
Es merkt sich nicht nur den Stackpointer, sondern auch das SREG.
Beim 8051 geht das nicht, da läßt sich ein Interrupt nur mit RETI 
beenden.

Das goto muß sich nichts merken, da ja innerhalb einer Funktion nichts 
am Stack gedreht wird.

Das goto ist ganz nützlich innerhalb eines switch/case, wenn am Ende 
einiger case immer das gleiche gemacht werden muß.
In dem Fall ist goto schöner als copy&paste.
Das switch/case verhält sich ja selber wie ein goto.


Peter

von Peter D. (peda)


Lesenswert?

Paul Hamacher schrieb:
> Sobald die Zahl eingegeben
> wurde ist die Funktion zuende und es geht weiter im Code.

Das ist dann quasi eine Statemaschine, wo der Programmcounter der 
aktuelle State ist.
Sowas wird früher oder später eine Sackgasse. Irgendwas dürfen nicht 
mehr alle Aufgaben stehen, nur weil man gerade etwas eingibt.


Karl Heinz Buchegger schrieb:
> Man kann aber auch eine schöne Struktur erfinden, die ein Eingabefeld
> beschreibt und dann für eine Eingabeseite ein Array aus derartigen
> Objekten machen.

Ja, genau das ist die übliche Methode. Die Eingabefunktion guckt nur 
kurz nach, ob eine Taste gedrückt wurde und macht die entsprechende 
Aktion. Danach gehts mit den anderen Tasks weiter.

Blockierende Schleifen gibt es nicht in einer Task. Jede Task arbeitet 
abweisend (if gerade nichts zu tun: return).
Nur die Mainloop ist die einzige Endlosschleife.


Peter

von Mark B. (markbrandis)


Lesenswert?

Johann L. schrieb:
> In GNU-C kann man Adressen von Labels nehmen und goto indirekt
> verwenden:
>
1
int weird_goto (unsigned x)
2
> {
3
>     static void **labels[] = { &&a, &&b, &&c };
4
> 
5
>     if (x >= sizeof (labels) / sizeof (labels[0]))
6
>         return -1;
7
> 
8
>     goto *labels[x];
9
> 
10
>     a:  return 1;
11
>     b:  return 2;
12
>     c:  return 0;
13
> }


Nette Sache. Mit anderen Compilern geht das nicht? Sonst wäre es ein 
klarer Contender für den IOCCC. ;-)

von Klaus W. (mfgkw)


Lesenswert?

Zumindest könnte man einmal über die Labels laufen, um mehrere 
sigjmp_buf zu füllen und die dann später für die Sprünge nehmen.
Ich glaube, es steht nirgends geschrieben, daß man ein sigjmp_buf nur 
einmal nehmen darf :-)

Das wäre zumindest auf dem Papier ziemlich portabel.

von Karl H. (kbuchegg)


Lesenswert?

Mark Brandis schrieb:

> Nette Sache. Mit anderen Compilern geht das nicht?

Nope. Ist kein Standard-C

Wenn man sowas nicht hat, nimmt man einfach zb ein switch-case oder eine 
andere Konstuktion mit der dasselbe erreichbar ist.  :-)
1
int weird_goto (unsigned x)
2
{
3
  switch( x )
4
  {
5
    case 0:
6
      return 1;
7
8
    case 1:
9
      return 2;
10
11
    case 2:
12
      return 0;
13
14
    default:
15
      return -1;
16
  }
17
}

Zugegebe: Ist manchmal etwas mehr Schreibaufwand, aber so schlimm ist es 
dann auch wieder nicht.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.