do{}while(false); -- ein besseres goto?



  • ja



  • ;fricky schrieb:

    volkard schrieb:

    Theoretisch vielleicht noch bei bestimmten endlichen Automaten, aber so einen habe ich in der Praxis noch nicht gesehen.

    ich auch nicht. state machines kenne ich nur mit verschachtelten switch/cases (meistens als output eines codegenerators, sowas von hand zu programmieren ist ziemlich übel), oder tabellengesteuert. und in oop-sprachen werden zustandsautomaten oft mit hilfe von vererbung gebastelt (class SomeState extends State, usw.).
    🙂

    Ne, StateMachines bastel' ich anders, weil die Generatoren so häßliche switch-case Kaskaden abliefern. Ich vermute, daß das woanders auch schonmal gemacht wurde, aber ich hab's mal für mich so schematisiert:
    Jeder Zustand ist eine Funktion, bedient sich aus Input, generiert Output und Folgezustand und liefert den als Funktionspointer zurück. Die aufrufende Routine (meist Timer- Interrupt) dereferenziert den Pointer und kriegt den Folgepointer zurück.
    Damit kriegt man auch händisch Automaten hin, die lesbar bleiben und gutes Laufzeitverhalten haben.



  • pointercrash() schrieb:

    Ich hab' jetzt den Thread hier so mitverfolgt und falle aus allen Wolken 😮 .

    goto auf feste Sprungmarken ist doch langweilig. Stell Dir vor, der gcc Compiler unterstützt Zeiger auf Sprungmarken. Man kann einen Zeiger deklarieren, diesen zur Laufzeit setzen, und irgendwo im Code einfach goto Zeiger machen. 😉



  • abc.w schrieb:

    pointercrash() schrieb:

    Ich hab' jetzt den Thread hier so mitverfolgt und falle aus allen Wolken 😮 .

    goto auf feste Sprungmarken ist doch langweilig. Stell Dir vor, der gcc Compiler unterstützt Zeiger auf Sprungmarken. Man kann einen Zeiger deklarieren, diesen zur Laufzeit setzen, und irgendwo im Code einfach goto Zeiger machen. 😉

    nicht ganz, was du meinst, aber schon mächtiger als goto: man: sigsetjmp(3)



  • supertux schrieb:

    nicht ganz, was du meinst, aber schon mächtiger als goto: man: sigsetjmp(3)

    nein, ich meine das hier http://gcc.gnu.org/onlinedocs/gcc-4.4.1/gcc/Labels-as-Values.html#Labels-as-Values



  • supertux schrieb:

    abc.w schrieb:

    pointercrash() schrieb:

    Ich hab' jetzt den Thread hier so mitverfolgt und falle aus allen Wolken 😮 .

    goto auf feste Sprungmarken ist doch langweilig. Stell Dir vor, der gcc Compiler unterstützt Zeiger auf Sprungmarken. Man kann einen Zeiger deklarieren, diesen zur Laufzeit setzen, und irgendwo im Code einfach goto Zeiger machen. 😉

    nicht ganz, was du meinst, aber schon mächtiger als goto: man: sigsetjmp(3)

    Nee, er meint schon goto auf Zeiger. Kleine gcc-Erweiterung, damit man in C++ nicht langsamer als in assembler ist.



  • abc.w schrieb:

    goto auf feste Sprungmarken ist doch langweilig. Stell Dir vor, der gcc Compiler unterstützt Zeiger auf Sprungmarken. Man kann einen Zeiger deklarieren, diesen zur Laufzeit setzen, und irgendwo im Code einfach goto Zeiger machen.

    naja, dafür hat man ja function pointer. nichts gegen 'goto', aber man kanns auch übertreiben.

    pointercrash() schrieb:

    ...Jeder Zustand ist eine Funktion, bedient sich aus Input, generiert Output und Folgezustand und liefert den als Funktionspointer zurück. Die aufrufende Routine (meist Timer- Interrupt) dereferenziert den Pointer und kriegt den Folgepointer zurück.

    das nennt sich dann, glaub ich, eine 'mealy machine'. aber klar, man kann sich die wildesten konstruktionen bauen, hauptsache das fest definierte verhalten wird garantiert, was ja die stärke solcher maschinen ist und was ziemlich komplexe abläufe 100% stabil und leicht handhabbar macht.
    🙂



  • ;fricky schrieb:

    naja, dafür hat man ja function pointer. nichts gegen 'goto', aber man kanns auch übertreiben.

    Dieses feature ist ziemlich wichtig für Emulatoren, die nicht für jeden emulierten Befehl den overhead eines Funktionsaufrufs haben wollen. Die bauen nämlich sowas dann ganz gerne in Assembler nach.



  • otze schrieb:

    ;fricky schrieb:

    naja, dafür hat man ja function pointer. nichts gegen 'goto', aber man kanns auch übertreiben.

    Dieses feature ist ziemlich wichtig für Emulatoren, die nicht für jeden emulierten Befehl den overhead eines Funktionsaufrufs haben wollen.

    ok, aber switch/case sollte es auch tun. eine switch-anweisung könnte man ja auch als 'berechnetes goto' bezeichnen.
    🙂



  • ;fricky schrieb:

    switch/case sollte es auch tun. eine switch-anweisung könnte man ja auch als 'berechnetes goto' bezeichnen.
    🙂

    Naja, goto auf Zeiger ist schon ne Klasse besser.



  • ;fricky schrieb:

    das nennt sich dann, glaub ich, eine 'mealy machine'. aber klar, man kann sich die wildesten konstruktionen bauen, hauptsache das fest definierte verhalten wird garantiert, was ja die stärke solcher maschinen ist und was ziemlich komplexe abläufe 100% stabil und leicht handhabbar macht.
    🙂

    Klar ist das ein Mealy- Automat, aber um sicherzustellen, daß keine parasitären Zyklen entstehen, mußtest Du das Ding bei allen Codegeneratoren (hab' vor etwa 3 Jahren die Opensource- Projekte zu dem Thema durchforstet) komplett ausdefinieren, als Ergebnis liefern die Dinger eine voll fette switch/case- Orgie ab, die man weder gut lesen kann noch performant ist, weil sie viel Irrelevantes mitprüft.
    So 'ne schöne "don't care- Eliminierung" wie sie ABEL oder VHDL immanent bieten, hatten die bestenfalls auf der "todo- Liste".
    Auf drei Vorteile wollte ich beim "Handschnitzen" hinaus:

    - Dont't Cares erzeugen keine Source, nichtexistente Source kann keine parasitären Zyklen bilden.
    - Das Programm bleibt mit Deinen Bezeichnern und Deiner Logik voll debugbar. Wenn Du mal was übersehen hast und Dein Automat "hängt", siehst Du das eigentlich sofort.
    - Wenn Du statt Tokens für Zustände gleich den Pointer auf den Folgezustand zurückgibst, sparst Du eine switch/case- Stufe in Source und Laufzeit.

    Ideal für Ablaufsteuerungen kann man aber auch andere Dinge in einen Mealy- Automaten pressen: Menüsysteme, Busprotokolle usw.
    Und weil immer nur kleine Softwarehäppchen abgearbeitet werden, ergibt sich vor allem bei schwächeren µCs ein ausgeglichenes Laufzeitverhalten, weil's auf ein "Multitasking für Arme" hinausläuft. 😉


Anmelden zum Antworten