Die verpönten goto´s



  • earli schrieb:

    Mein Punkt ist, dass man beides nicht messen kann.

    Eine Abschätzung reicht.

    earli schrieb:

    Meine Regel sollte ja auch nur eine "Faustregel" sein. Und als solche ist sie klar anwendbar.

    Mit Deiner Regel kannst Du Dir den Hintern abwischen.



  • rüdiger schrieb:

    knivil schrieb:

    aber das goto ist in dem Fall ganz in Ordnung ... manchmal ist ein goto zwingend oder die beste Wahl ... Goto nach vorn ist okay ... Goto ist okay, wenn keine Alternative einfacher ist.

    Ich habe noch nie ein goto fuer noetig gehalten. Es gab immer eine bessere Alternative.

    Bei der Fehlerbehandlung sind die in C oft praktisch

    void foo() {
      allocateX();
      allocateY();
    
      if(!a())
        goto cleanup;
    
      if(!b())
        goto cleanup;
    
      c();
    
    cleanup:
      freeX();
      freeY();
    }
    

    Kein gutes Beispiel, da einfacher:

    void foo() {
      allocateX();
      allocateY();
    
      if(a() && b())
        c();
    
      freeX();
      freeY();
    }
    


  • schpätli schrieb:

    earli schrieb:

    Mein Punkt ist, dass man beides nicht messen kann.

    Eine Abschätzung reicht.

    Das ist doch gar nicht das Problem. Lesbarkeit ist einfach sehr subjektiv. Und wenn in einer großen Gruppe von Programmierern (zum Beispiel bei Linux -- wo goto unabdingbar ist, da ständig viele Locks auf Ressourcen angelegt und aufgehoben werden -- kamen Patches von über 2000 Personen im Jahr 2009) keine klare Regel angibst, hast du einfach verkackt.



  • earli schrieb:

    Kein gutes Beispiel, da einfacher:

    void foo() 
    {
      allocateX();
      allocateY();
    
      if(a() && b())
        c();
    
      freeX();
      freeY();
    }
    
    void foo (void)  // hier gehört "void" in die Klammer
    {
      allocateX();
      allocateY();
    
      if (...)
      {
         for(...)
         {
            while (...)
            {
                do(...)
                {
                    if (error) goto exit;
                }
            }
         }
      }
      c();
    
    exit:
      freeX();
      freeY();
    }
    


  • earli schrieb:

    Lesbarkeit ist einfach sehr subjektiv.

    Eigentlich nicht, das ist wie mit gutem Geschmack, der ist bei vielen gleich und nur wenige unterscheiden sich davon.

    Es mag Menschen geben, die empfinden Source http://www.de.ioccc.org/years.html dieses Types als leserlich, aber der Prozentsatz ist doch relativ klein 😉



  • noobLolo schrieb:

    earli schrieb:

    Lesbarkeit ist einfach sehr subjektiv.

    Eigentlich nicht, das ist wie mit gutem Geschmack, der ist bei vielen gleich und nur wenige unterscheiden sich davon.

    Es mag Menschen geben, die empfinden Source http://www.de.ioccc.org/years.html dieses Types als leserlich, aber der Prozentsatz ist doch relativ klein 😉

    Es gibt trotzdem verschiedene Lager, z.B.

    - http://en.wikipedia.org/wiki/GNU_Coding_Standards
    - http://en.wikipedia.org/wiki/Hungarian_notation
    - http://lxr.linux.no/#linux+v2.6.32/Documentation/CodingStyle
    - http://blogs.msdn.com/brada/articles/361363.aspx



  • earli schrieb:

    Es gibt trotzdem verschiedene Lager, z.B.

    Ja da hast du natürlich Recht, allerdings find ich 4-5 große verschiedene Formatierungen bei xTausend Programmierern eigentlich recht wenig, aber darauf wollt ich nicht hinaus, wir können ja mal über Code von gerstern abstimmen,

    von mir

    lolo_matrix matrixMultiply(lolo_matrix a,lolo_matrix b){
        lolo_matrix c;
        int l,ll,lll,cache;
        int *aa,*bb,*cc,*bDataCache = b.data,*cDataCache;
        c.cols = a.rows;
        c.rows = b.cols;
        c.data = malloc(sizeof(*c.data)*c.cols*c.rows);
    
        if(c.data){
            cDataCache = c.data;
            lll = a.rows;
            while(lll--){
                ll = a.cols;
                while(ll--){
                    l = c.cols;
                    cc = c.data-1;
                    aa = a.data++;
                    bb = b.data;
                    b.data+=b.cols;
                    cache = *aa;
                    while(l--){
                        *++cc += cache * *bb++;
                    }
                }
                b.data = bDataCache;
                c.data += c.cols;
            }
            c.data = cDataCache;
        }
        return c;
    }
    

    von Big Brother

    // E = A * B
    void multiplikation ( Matrix* E, Matrix* A, Matrix* B ) {
        unsigned s, z, k;
        assert ( A->s == B->z );
        for ( z = 0; z < A->z; z++ )
            for ( s = 0; s < B->s; s++ )
                for ( k = 0; k<A->s; k++ )
                        E->m[z*E->s+s] += A->m[z*A->s+k] * B->m[k*B->s+s];
    }
    

    Ich denke wir müssen uns nicht darüber unterhalten was schöner ist oder?



  • Also mir gefällt der Code von Big Brother besser, aber der Style von noobLolo (diese ganzen Leerzeichen bei den Klammern von Big Brother kann ich gar nicht leiden :D).

    Nachtrag: Die Sternchen gehören bei mir auch an die Variablen.

    So sähe das bei mir eher aus:

    /*
     *  E = A * B
     */
    void multiplikation(Matrix *E, Matrix *A, Matrix *B) {
        unsigned s, z, k;
        assert(A->s == B->z);
        for (z = 0; z < A->z; z++)
            for (s = 0; s < B->s; s++)
                for (k = 0; k<A->s; k++)
                        E->m[z*E->s+s] += A->m[z*A->s+k] * B->m[k*B->s+s];
    }
    


  • earli schrieb:

    Also mir gefällt der Code von Big Brother besser, aber der Style von noobLolo (diese ganzen Leerzeichen bei den Klammern von Big Brother kann ich gar nicht leiden :D).

    Ja, als ich den Code von Big Brother gesehen hab, mußte ich natürlich auch eingestehen das er viel schneller erfaßbar ist. Und da sind wir sicher nicht die einzigen, sondern 99.9% werden so denken.

    0.1% war ich, denn ich hab ja den anderen gebastelt, mit der Intention die 2 Multiplikationen für die 2. Dimension zu vermeiden, aber als ich dann den compiler auf -O3 gestellt hab waren die wieder drin 🙄



  • [quote="noobLolo"]

    earli schrieb:

    0.1% war ich, denn ich hab ja den anderen gebastelt, mit der Intention die 2 Multiplikationen für die 2. Dimension zu vermeiden, aber als ich dann den compiler auf -O3 gestellt hab waren die wieder drin 🙄

    Das ist auch mal ganz grober Unfug. Multiplikationen sind Kinderkacke, wenn du in jedem Durchlauf zig Pointer dereferenzierst.



  • earli schrieb:

    Multiplikationen sind Kinderkacke

    Kinderkacke macht meine cpu mit einem Takt, Multiplikationen nicht 😉



  • schpätli schrieb:

    void foo (void)  // hier gehört "void" in die Klammer
    {
      allocateX();
    ...
    }
    

    Wir koennen jetzt gerne weitere tolle, allgemeine und nichts-sagende Beispiele entwerfen. Aber ich wuerde so einen Code nie schreiben. Und es liegt nicht am goto.

    "Faustregel"



  • noobLolo schrieb:

    earli schrieb:

    Multiplikationen sind Kinderkacke

    Kinderkacke macht meine cpu mit einem Takt, Multiplikationen nicht 😉

    Näherungsweise schon, wenn du jetzt nicht gerade mit einem 286er unterwegs bist. (Stichwort: Pipelining.) Und die for-Schleifen machen das Ganze so vorhersehbar für den Compiler, dass nichtmal branch prediction erforderlich ist.



  • earli schrieb:

    Das ist auch mal ganz grober Unfug. Multiplikationen sind Kinderkacke, wenn du in jedem Durchlauf zig Pointer dereferenzierst.

    Ne, spielt keine so große Rolle, weil die meisten Compiler Variablenzugriffe sowieso auf indirekt- indizierten ASM abzubilden versuchen. Weil man so das meiste gebacken bekommt oder sich sonst was mit einem möglichen OS beißt, plagt sich kaum jemand mit auf direkter Adressierung basierender Optimierung rum.
    Ist jetzt eine sehr verkürzte Darstellung und sachlich im Detailbereich nicht zu 100% richtig, aber Deref's sind meistens ziemlich egal, weil der Frame eigentlich immer auch indirekt- indiziert aufgelöst wird.

    Zum Topic:
    Ich habe die gotos für cleanups seit etwa einem Jahr wiederentdeckt und etliche Zeilen Sinnlos- Code aus meinen Libs geschmissen, was zeigt, daß goto nicht nötig ist, aber manchmal saupraktisch und besser lesbaren Code zu erzeugen helfen kann.

    @Lolo
    Ich mag BB's Code auch lieber, weil eher 'Spirit of C'.
    😃



  • knivil schrieb:

    Wir koennen jetzt gerne weitere tolle, allgemeine und nichts-sagende Beispiele entwerfen.

    Also für mich war die Message jedes Beispieles immer leicht versändlich

    knivil schrieb:

    Aber ich wuerde so einen Code nie schreiben. Und es liegt nicht am goto.

    Dann zeig doch mal wie du das machen würdest (am besten anhand eines Beispieles), und jetzt komm nicht mit nem statischen Array daher... :p



  • Dann zeig doch mal wie du das machen würdest (am besten anhand eines Beispieles)

    Hast du ein konkretes Problem?



  • pointercrash() schrieb:

    earli schrieb:

    Das ist auch mal ganz grober Unfug. Multiplikationen sind Kinderkacke, wenn du in jedem Durchlauf zig Pointer dereferenzierst.

    Ne, spielt keine so große Rolle, weil die meisten Compiler Variablenzugriffe sowieso auf indirekt- indizierten ASM abzubilden versuchen. Weil man so das meiste gebacken bekommt oder sich sonst was mit einem möglichen OS beißt, plagt sich kaum jemand mit auf direkter Adressierung basierender Optimierung rum.

    Es handelt sich aber nicht um gewöhnliche Variablenzugriffe, sondern auf Zugriffe in den Heap (malloc()) oder auf unbekannte Variablen im Stack von den aufrufenden Funktionen. Dein Trick geht nur mit Variablen auf dem Stacksegment der Funktion selbst oder mit statischen Fields.



  • knivil schrieb:

    Dann zeig doch mal wie du das machen würdest (am besten anhand eines Beispieles)

    Hast du ein konkretes Problem?

    Herausspringen aus dreifacher Verschachtelung z.B. Und sag nicht, Du willst das mit einem Flag machen, oder den Code nur deshalb in eine Funktion auslagern.



  • Herausspringen aus dreifacher Verschachtelung

    Das ist kein konkretes Problem. Wahrscheinlich wuerde ich keine dreifach verschachtelte Schleife schreiben.

    jetzt komm nicht mit nem statischen Array daher ... Flag machen ... Funktion auslagern

    Du verbietest pauschal ganz schoen viel, ohne ein konkretes Problem genannt zu haben.



  • knivil schrieb:

    Herausspringen aus dreifacher Verschachtelung

    Das ist kein konkretes Problem. Wahrscheinlich wuerde ich keine dreifach verschachtelte Schleife schreiben.

    Wie machst du dann eine Matrixmultiplikation?


Anmelden zum Antworten