Tom: Coding Conventions

Hello,

wie werden diese Zeilen

$i = 10;
    (while machwas() && $i--)
    {
        # ...
    }

und

$i = 10;
    (while machwas() && $--i)
    {
        # ...
    }

in PHP und in anderen Sprachen, C, C++, usw., auf den unterscheidlichen Plattformen bei ggf. unterschiedlichen Compilern ausgewertet, solange machwas()  immer true liefert?

Gibt es da Unterschiede?

Liebe Grüße aus Syburg bei Dortmund

Tom vom Berg

--
Nur selber lernen macht schlau
http://bergpost.annerschbarrich.de
  1. Hello,

    (while machwas() && --$i)

    sollte das heißen. Bevor einer sich darauf bezieht :-)

    Liebe Grüße aus Syburg bei Dortmund

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
  2. Hallo,

    $i = 10;
        while (machwas() && $i--)
        while (machwas() && --$i)
    in PHP und in anderen Sprachen, C, C++, usw., auf den unterscheidlichen Plattformen bei ggf. unterschiedlichen Compilern ausgewertet, solange machwas()  immer true liefert?

    Gibt es da Unterschiede?

    Wenn machwas() true liefert, dann wird $i immer dekrementiert (in allen Sprachen). Allerdings gibt --$i den dekrementierten Wert zurück und $i-- den Wert vor dem Dekrementieren. Sprich: Die erste Schleife hat 10 Durchläufe, die zweite Schleife hat 9 Durchläufe (solange die Schleife selbst $i nicht modifiziert).

    Wenn machwas() false liefert, dann kommt es darauf an. Bei PHP und C wird $i-- und --$i *nie* ausgewertet (der Sprachstandard garantiert es), bei C++ kommt es darauf an, ob der &&-Operator für die Operhandentypen überladen wurde - wenn ja, dann wird es ausgewertet, auch wenn machwas() false ist, wenn er nicht überladen wurde, dann nicht (das ist auch übrigens etwas, was viele Leute an C++ kritisieren).

    Viele Grüße,
    Christian

    1. Hello Christian,

      Wenn machwas() false liefert, dann kommt es darauf an. Bei PHP und C wird $i-- und --$i *nie* ausgewertet (der Sprachstandard garantiert es), bei C++ kommt es darauf an, ob der &&-Operator für die Operhandentypen überladen wurde - wenn ja, dann wird es ausgewertet, auch wenn machwas() false ist, wenn er nicht überladen wurde, dann nicht (das ist auch übrigens etwas, was viele Leute an C++ kritisieren).

      Danke für den Tipp.
      Das könnte die Ursache für die Fehler sein, die ich suche.

      Liebe Grüße aus Syburg bei Dortmund

      Tom vom Berg

      --
      Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
    2. Wenn machwas() false liefert, dann kommt es darauf an. Bei PHP und C wird $i-- und --$i *nie* ausgewertet (der Sprachstandard garantiert es), bei C++ kommt es darauf an, ob der &&-Operator für die Operhandentypen überladen wurde - wenn ja, dann wird es ausgewertet, auch wenn machwas() false ist, wenn er nicht überladen wurde, dann nicht (das ist auch übrigens etwas, was viele Leute an C++ kritisieren).

      Kleine Nebenfrage, da ich mich mit C++ nicht auskenne: Passiert das immer, wenn der &&-Operator überladen wurde oder hängt das von demjenigen ab, der überlädt (sprich: Der Programmierer, der die Überladung programmiert hat, hat die Wahl, ob dieses oder jenes Verhalten auftritt)?

      --
      Reden ist Silber, Schweigen ist Gold, meine Ausführungen sind Platin.
      Self-Code: sh:( ch:? rl:( br:> n4:( ie:{ mo:) va:) de:> zu:} fl:| ss:| ls:~ js:|
      1. Hello,

        Kleine Nebenfrage, da ich mich mit C++ nicht auskenne: Passiert das immer, wenn der &&-Operator überladen wurde oder hängt das von demjenigen ab, der überlädt (sprich: Der Programmierer, der die Überladung programmiert hat, hat die Wahl, ob dieses oder jenes Verhalten auftritt)?

        Ich hatte da noch ganz tief im Hinterhirn, dass es sogar mit den unterschiedlichen Compilern zusammenhängen kann, wie eine Programmzeile aufgelöst wird, von rechts nach links, von links nach rechts, usw.

        Aber dieses Problem traf sicher jetzt nicht auf die von mir zitierte Konstruktion zu.

        Liebe Grüße aus Syburg bei Dortmund

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
      2. Hallo,

        Wenn machwas() false liefert, dann kommt es darauf an. Bei PHP und C wird $i-- und --$i *nie* ausgewertet (der Sprachstandard garantiert es), bei C++ kommt es darauf an, ob der &&-Operator für die Operhandentypen überladen wurde - wenn ja, dann wird es ausgewertet, auch wenn machwas() false ist, wenn er nicht überladen wurde, dann nicht (das ist auch übrigens etwas, was viele Leute an C++ kritisieren).
        Kleine Nebenfrage, da ich mich mit C++ nicht auskenne: Passiert das immer, wenn der &&-Operator überladen wurde oder hängt das von demjenigen ab, der überlädt (sprich: Der Programmierer, der die Überladung programmiert hat, hat die Wahl, ob dieses oder jenes Verhalten auftritt)?

        Ja und nein. Wenn Du den &&-Operator überlädst, gibst Du ja die Klassen der Parameter mit an (für primitive Datentypen alleine kannst Du das nicht überladen). D.h. wenn das weiterhin boolsche Ausdrücke sind, dann passiert Dir in C++ nichts. Wenn Du aber den &&-Operator für eine Klasse Foo überlädst, und in dem obigen Beispiel machwas() ein Objekt dieser Klasse zurückgibt, dann würde in C++ der Dekrement *immer* durchgeführt werden...

        Sprich: Sobald er überladen ist, gilt die überladene Variante immer. Allerdings überlädst Du ihn ja nur für spezifische Datentypen. Das macht es allerdings nicht arg weniger verwirrend.

        Wenn Du auf Nummer Sicher gehen willst, kannst Du (bool)A && (bool)B machen, um explizit boolsche Ausdrücke miteinander zu vergleichen, dann wird er nie überladen.

        (Mein Wissensstand, ist von mir jetzt nicht getestet worden...)

        Viele Grüße,
        Christian

        1. Ja und nein. Wenn Du den &&-Operator überlädst, gibst Du ja die Klassen der Parameter mit an (für primitive Datentypen alleine kannst Du das nicht überladen). D.h. wenn das weiterhin boolsche Ausdrücke sind, dann passiert Dir in C++ nichts. Wenn Du aber den &&-Operator für eine Klasse Foo überlädst, und in dem obigen Beispiel machwas() ein Objekt dieser Klasse zurückgibt, dann würde in C++ der Dekrement *immer* durchgeführt werden...
          Sprich: Sobald er überladen ist, gilt die überladene Variante immer. Allerdings überlädst Du ihn ja nur für spezifische Datentypen. Das macht es allerdings nicht arg weniger verwirrend.

          Achso, das beim Vergleich boolscher Ausdrücke weiterhin die nicht überladene Variante gilt, hätte ich noch gewusst, trotzdem danke für die Erklärung. Woher kommt dieses Verhalten? Liegt das vielleicht daran, dass erst beide Ausdrücke ausgewertet werden müssen, um herauszubekommen, welche der Überladungen überhaupt benutzt wird?

          Wenn Du auf Nummer Sicher gehen willst, kannst Du (bool)A && (bool)B machen, um explizit boolsche Ausdrücke miteinander zu vergleichen, dann wird er nie überladen.

          Ist das zweite (bool) nicht überflüssig? Oder "sieht" der Compiler, dass dort auf jeden Fall zwei boolsche Ausdrücke vorliegen und nimmt nur dann die Optimierung vor?

          --
          Reden ist Silber, Schweigen ist Gold, meine Ausführungen sind Platin.
          Self-Code: sh:( ch:? rl:( br:> n4:( ie:{ mo:) va:) de:> zu:} fl:| ss:| ls:~ js:|
          1. Hallo,

            Achso, das beim Vergleich boolscher Ausdrücke weiterhin die nicht überladene Variante gilt, hätte ich noch gewusst, trotzdem danke für die Erklärung. Woher kommt dieses Verhalten? Liegt das vielleicht daran, dass erst beide Ausdrücke ausgewertet werden müssen, um herauszubekommen, welche der Überladungen überhaupt benutzt wird?

            Nein, das nicht, der Rückgabedatentyp von Funktionen ist ja bekannt. Das Problem ist, wenn Du sowas hast wie bool operator&&(Foo a, Bar b), dann kann die überladene Funktion ja nur aufgerufen werden, wenn beide Operhanden ausgewertet wurden.

            Wenn Du auf Nummer Sicher gehen willst, kannst Du (bool)A && (bool)B machen, um explizit boolsche Ausdrücke miteinander zu vergleichen, dann wird er nie überladen.
            Ist das zweite (bool) nicht überflüssig? Oder "sieht" der Compiler, dass dort auf jeden Fall zwei boolsche Ausdrücke vorliegen und nimmt nur dann die Optimierung vor?

            Nur, wenn beides primitive Datentypen sind, ist der Cast überflüssig. Und Du als Mensch siehst es halt nicht immer explizit, wenn da while (doSomething() && isSomething()) steht...

            Viele Grüße,
            Christian