Hallo!
Habe folgendes Problem:
Will einen Befehl mit 2 Bedingungen machen... Von früher bin ich der Meinung, dass ich das ja mit einem And verknüpfen muss...
Leider weiß ich nciht mehr, wie das geht Habe es mit Klammern setzen probiert, ging auch nicht...
Kann mir da einer helfen?
var a:array[0..4] of boolean;
i:integer;
begin
..
i := 5;
if (i <= high(a)) and (a[i]) then
Foo;
Ist Erlaubt, da die Short Circuit Evaluation a nicht auswertet, da ja (i<= high(a)) bereits false war. Hier sind auch keine Nebeneffekte, machst du stattdesen aber folgendes :
var globalnumber:integer;
function a():Boolean;
begin
globalnumber := globalnumber + 1;
// Ermittlung des Ergebnisses unbekannt
end;
funktion b():boolean;
begin
globalnumber := globalnumber * 2;
end;
begin
globalnumber := 1;
if a() and b() then foo();
Bar();
Greift nun Bar() auf globalnumber zu und gehen wir davon aus das Foo(); globalnumber nicht verändert, so sind für globalnumber die Werte 2 und 4 möglich...
corpsman hat geschrieben:Ergänzend sei noch die Short Circuit Evaluation genannt.
Wenn du in deinem and Funktionen aufrufst, welche Nebeneffekte haben, werden diese evtl nicht gesetzt.
Meiner Meinung nach sollte man darauf nur bei trivialen Nebeneffekten (String-, Array-, Listengrenzen) aufbauen. Bei komplexeren Nebeneffekten sollte man sich schon die Mühe machen einfacher zu verstehenden Quelltext zu schreiben.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
var a:array[0..4] of boolean;
i:integer;
begin
..
i := 5;
if (i <= high(a)) and (a[i]) then
Foo;
Ist Erlaubt, da die Short Circuit Evaluation a[ i ] nicht auswertet, da ja (i<= high(a)) bereits false war.
Irre ich mich, oder ist die Reihenfolge, in der die Ausdruecke ausgewertet werden nicht undefiniert? Ich kann mich dunkel erinnern, gelesen zu haben, dass die Auswertung durchaus auch beim letzten Ausdruck beginnen (und damit auch abbrechen) kann.
Ein Grund mehr, sehr vorsichtig damit zu sein ...
Zuletzt geändert von Eclipticon am Mi 4. Mai 2011, 16:58, insgesamt 1-mal geändert.
Eclipticon hat geschrieben:
Irre ich mich, oder ist die Reihenfolge, in der die Ausdruecke ausgewertet werden nicht undefiniert? Ich kann mich dunkel erinnern, gelesen zu haben, dass die Auswertung durchaus auch beim letzten Ausdruck beginnen (und damit auch abbrechen) kann.
Die Reihenfolge, in der die Ausdruecke der selben mathematischen Prioritaet ausgewertet werden, geht nicht immer unbedingt von rechts nach links [sic!]. Grundsaetzlich darf nicht von einer gesicherten Reihenfolge bei der Bearbeitung ausgegangen werden. [...] Deshalb kann im folgenden Ausdruck
a:= g(3) + f(2);
f(2) vor g(3) ausgefuehrt werden. Dieses Verhalten weicht von dem von Delphi und Turbo Pascal ab.
(van Canneyt, Free Pascal 2, p. 223)
Auf der anderen Seite ... das widerspricht etwas der Dokumentation und der Intention von {$Bx} ... wird in diesem Fall also wohl schon der Reihe nach erfolgen.
Eclipticon hat geschrieben:Irre ich mich, oder ist die Reihenfolge, in der die Ausdruecke ausgewertet werden nicht undefiniert? Ich kann mich dunkel erinnern, gelesen zu haben, dass die Auswertung durchaus auch beim letzten Ausdruck beginnen (und damit auch abbrechen) kann.
Das habe ich auch mal gelesen. In dem ursprünglichen Pascal-Dialekt von N.Wirth war das auch so definiert um dem Compiler diverse Optimierungen zu ermöglichen; in der Free Pascal-Dokumentation finde ich aber kein Wort dazu (also ist hier das Verhalten bei {$B-} nicht dokumentiert und nicht einfach alles der Reihe nach!).
Meine Interpretation wäre, dass beides gleichzeitig trotzdem gültig ist, da der Compiler sich auch dafür entscheiden kann alles in der Reihenfolge des Quelltextes auszuwerten. Das wäre dann in etwa der Unterschied zwischen Sprachdefinition und Implementation durch den Compiler.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ich kann nur sagen, dass ich bisher immer davon ausgegangen bin, dass {$B-} von LnR arbeitet, und ich hatte nie ein Problem damit (FPC und Delphi).
Hier steht's dann auch noch explizit:
In the {$B-} state, the compiler generates code for short-circuit Boolean expression evaluation, which means that evaluation stops as soon as the result of the entire expression becomes evident in left to right order of evaluation.
Die Reihenfolge, in der die Ausdruecke der selben mathematischen Prioritaet ausgewertet werden, geht nicht immer unbedingt von rechts nach links [sic!]. Grundsaetzlich darf nicht von einer gesicherten Reihenfolge bei der Bearbeitung ausgegangen werden. [...] Deshalb kann im folgenden Ausdruck
a:= g(3) + f(2);
f(2) vor g(3) ausgefuehrt werden. Dieses Verhalten weicht von dem von Delphi und Turbo Pascal ab.
(van Canneyt, Free Pascal 2, p. 223)
Auf der anderen Seite ... das widerspricht etwas der Dokumentation und der Intention von {$Bx} ... wird in diesem Fall also wohl schon der Reihe nach erfolgen.
Für den Fall "AND" und "OR" macht es ja auch Sinn, das ganze in seiner Reihenfolge zu belassen.
Und ja, es sei dir zugesichert, dass bei AND und OR immer die linke Seite zuerst ausgeführt wird und (sofern nicht anders umgestellt) die rechte Seite je nach Bedarf auch wegfällt.
MAC hat geschrieben:ich kann maik nur zustimmen. Lieber gleich angewöhnen viel klammern zu schreiben als die irgendow zu vergessen. Den Fehler findet man sonnst nie
lach hab ich mir schon in Basic angewöhnt bei TP beigehalten, bei µC war's zum Teil ein Zwang
ergo arbeite schon aus Prinzip so... Nur schade, das ich bei anderen Sachen net so konsquent bin.
Ubuntu 10.04 LTS ist meine Heimat. Lazarus ist meine Sprache und der Kreis Segeberg meine LIEBE