Und man sollte verstehen was man macht und wieso.
Eigentlich soll Computed Goto Distanzen berechnen können. Damit relative Gotos ermöglichen. Das gilt für unseren GCC, noch als broken.(soweit mir bekannt)
Also eine Warnung: Computed Gotos verwenden, ok. Aber bitte keine Rechenoperationen auf den Lable Adressen ausführen und dann anspringen. Das kann ins Auge gehen.
//----
Übrigens, eine Suche über meinen SketchOrdner, inklusive Libraries und Hardwaredefinitionen, führte über 1300 Gotos ans Licht. Auch, oder eher gerade, in namhaften Libraries.
//----
Du möchtest ja Beispiele sehen...... Hier ein Doppelblinker Beispiel, aus meiner Wühlkiste, für einen kleinen endlichen Automaten mit Goto:
const byte taster = 2;
class Blinker
{
protected:
const byte ledPin;
const unsigned long hellPhase;
const unsigned long dunkelPhase;
unsigned long zeitMerker = 0;
void *sprungZiel = 0; // zustandsmerker
public:
Blinker(const byte ledPin,const unsigned long hellPhase,const unsigned long dunkelPhase): ledPin(ledPin),hellPhase(hellPhase),dunkelPhase(dunkelPhase){}
void run(const bool blinkAnforderung)
{
if(!sprungZiel) sprungZiel = &&Start;
goto *sprungZiel;
Start:
if(!blinkAnforderung) return;
digitalWrite(ledPin,HIGH);
sprungZiel = &&HellPhase;
zeitMerker = millis();
HellPhase:
if(millis()-zeitMerker
Ob das jetzt ein gutes Beispiel ist, kann ich nicht sagen. Aber dennoch ist es mit Goto und dabei recht übersichtlich.
Bei der Verwendung von enum Switch/case würde der Compiler versuchen eine Sprungtabelle anzulegen. Dann würden sich erstmal keine Performance Vorteile, für Goto, ergeben.
Aber: Wenn die case nicht fortlaufend definiert sind, oder die Anzahl ein gewisses Maß überschreitet, dann generiert der Compiler ein Konstrukt, welches einer langen if Kette entspricht. Dann dauert es eben diese Anzahl Vergleiche, bis der betreffende Case erkannt und ausgeführt wird. Natürlich, je weiter ein Fall hinten steht, desto länger dauert es dann bis zur Ausführung.