frage zu if(bed1&&bed2&&bed3&&bed4&&..)



  • Du beachtest nur nicht, dass hier beschrieben wird, wie sich die abstrakte Maschine zu verhalten hat. Wie in meinem Quote nachzulesen ist, muss das aber nicht 1:1 auf die reale Maschine abgebildet werden.



  • Ringding schrieb:

    @DrGreenthumb: gutes Argument, aber der Compiler "weiß" ja, dass ein Pointerzugriff gefährlich sein kann, und dass er ihn deshalb nicht vorziehen darf. Der Compiler weiß auch, dass eine Division gefährlich ist.

    Ok, ich hatte vorhin gesagt EOD, aber jetzt reizt es mich doch nochmal, ein Argument in Anschlag zu bringen...

    Du sagst oben "der Compiler weiß" (dies und das)... Gut, gut. Bekanntlich (seit Turing) aber kann ein Compiler nicht alles wissen; vor allem kann er (prinzipiell) nicht wissen, ob eine Funktion (mit einem bestimmten Input) in eine Endlosschleife gerät, oder nocht! (Schön wär's ja, wenn Compiler d a s könnten!)

    Mit anderen Worten, es wäre, wenn der Compiler die Berechnung der Funktion vorzieht, völlig unbestimmt, ob er diese Berechnung je abschließt oder nicht. 🙂 [Es wäre also sehr "gefährlich", "komplexere" Funktionen vorzuziehen.]

    Nun magst Du einwenden, dass das sehr theoretisch ist. Ok.

    Nehmen wir nun aber mal das wesentlich realistischere Beispiel, dass die Funktion einfach eine relativ lange LAUFZEIT hat! Dann würde das einen MERKBAREN Unterschied machen, ob die Funktion vorgezogen wird oder nicht; auch dann wenn keine Seiteneffekte (im eigentlichen Sinne) auftreten: die Laufzeit ist allerdings für den Benutzer ein durchaus realer Effekt! Ich behaupte nun, dass dieser Effekt nicht auftreten DÜRFTE, wenn der Compiler dem Standard entsprechend implementiert ist.

    bool inline wait(double x) { Zählschleife // ca. 1 Sek. return 1; }
    [...]
    if (<bedingung> && wait(x)) { dosomething(); }
    

    Jetzt sag bitte nicht, der Compiler erkennt auch eine Zählschleife als solche, usw. usf - wir reden hier ja nicht über AI, sondern über einen C-Compieler; ich denke der hat anderes zu tun, als Funktionen auf ihre (umfassende) Funktion hin zu analysieren. 😉

    (Es muss noch nicht mal eine Zählschleife sein. Deine sin()-Funktion tut's im Grunde auch: Du selbst hast gesagt, dass ihre Berechnung relativ lange dauert. Und "ich" behaupte nun, dass dise Funktion eben erst gar nicht "evaluiert" wird, wenn die erste Bedingung nicht erfüllt ist, und so stehts auch im Standard.)



  • Bei deinem letzten Post gebe ich dir schon recht - das kann natürlich nur für ganz simple Sachen funktionieren und ist überhaupt sehr hypothetisch. Der Compiler muss auch den Inhalt der Funktion vollständig kennen, die ausgewertet wird.

    Trotzdem wäre das mit dem sin denkbar, denn moderne Prozessoren sind ja problemlos in der Lage, weiterzuarbeiten, während im Hintergrund die langwierige Sinusberechnung läuft. Vermutlich macht es auch nur dann Sinn, ihn vorzuziehen, wenn er soundso "fast immer" ausgeführt wird (diese Daten stehen ja bei Profile Guided Optimization zur Verfügung).



  • Ringding schrieb:

    Konsultieren wir den C99-Draft (was anderes hab ich gerade nicht hier, es wird aber nicht wesentlich anders sein):

    An implementation might define a one-to-one correspondence between abstract and actual semantics: at every sequence point, the values of the actual objects would agree with those specified by the abstract semantics.
    Alternatively, an implementation might perform various optimizations within each translation unit, such that the actual semantics would agree with the abstract semantics only when making function calls across translation unit boundaries. [...]

    Hmmm... ja...

    Dann aber heißt es da wiederum:

    Unlike the bitwise binary & operator, the && operator
    guarantees left-to-right evaluation; there is a sequence
    point after the evaluation of the first operand. If the
    first operand compares equal to 0, the second operand is not
    evaluated.

    Du meinst also, dass sich dies auf die "abstract semantics" bezieht. Aber ich kann mir nicht helfen...: Wenn der Compiler dann DOCH, wie Du sagst, die Berechnung der Funktion vorziehen kann, dann wirklich nur in dem Fall, dass auch garantiert GAR KEINE Seiteneffekte auftreten. Also so, dass es für den Programmablauf so ist, ALS OB die Funktion nicht aufgerufen worden wäre. (Das Laufzeitverhalten würde das allerdings u.U. ans Tageslicht bringen!)

    Ein Compiler müsste das also auch immer überprüfen, dass keine Seiteneffekte auftreten (und er müsste das perfekt können) ...Hmmm... (Man bedenke mal, wieviel der Compiler über Mathematik wissen müsste, um entscheiden zu können, welche mathematischen Funktionen nun "gefährlich" sind, und welche nicht, usw. usf.)

    Ein bissl "verrückt" ist das natürlich schon, wenn es einerseits im Standard heißt: "If the first operand compares equal to 0, the second operand is not
    evaluated." Andererseits

    if(0 && wait_some_time()) {...}

    u.U. dazu führt, dass das Programm tatsächlich eine Pause einlegt... 😞

    Kopfschüttel

    Was haben sich die Leute, die den Standard verbrochen haben, nur dabei gedacht... 😮



  • Ringding schrieb:

    [...] Vermutlich macht es auch nur dann Sinn, ihn vorzuziehen, wenn er soundso "fast immer" ausgeführt wird (diese Daten stehen ja bei Profile Guided Optimization zur Verfügung).

    Ja, verstehe, was Du meinst (habe ich mir gerade auch schon überlegt gehabt...).

    Was mich jetzt noch interessieren würde: Wie sieht es wohl damit in der PRAXIS aus, welche Compiler weichen hier u.U. wirklich von der "abstract semantics" ab (und unter welchen Umständen).

    Wenn es wirklich so ist, wie Du sagst, dann habe ich in jedem Fall wieder was dazugelernt! 🙂


Anmelden zum Antworten