Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Liest Delphi "Boolean-Abfragen" von links nach rechts?


WeBsPaCe - Sa 06.12.08 01:39
Titel: Liest Delphi "Boolean-Abfragen" von links nach rechts?
Tach,

ich hab leider keine Ahnung, nach was ich noch suchen könnte, um eine Antwort drauf zu bekommen. Hab ja sogar schon Probleme beim Titel formulieren... ;-)

Meine Frage ist, ob Delphi bei einer "Boolean-Abfrage" immer von links nach rechts durchgeht. Wichtig bei or-Verknüpfungen:

Delphi-Quelltext
1:
if (Func1) or (Func2) then ...                    

Welche Funktion wird zuerst auf Rückgabewert true geprüft?

Entstanden ist das Problem im Prinzip dabei:

Delphi-Quelltext
1:
2:
3:
repeat
...
until (True) or (Func1);

Ich müsste mir sicher sein, dass bei diesem Codeschnipsel Func1 niemals aufgerufen wird...

Danke schonmal, bin gespannt!

MfG,
WeBBy


Boldar - Sa 06.12.08 01:46

Normal wird von links nach rechts durchgegangen und abgebrochen, wenn der Wert klar ist, das lässt sich aber unter
Projekt-->Optionen-->Compiler-->vollst. Boolesche Auswertung
ändern.


platzwart - Sa 06.12.08 01:46

hi,

es werden immer alle ausdrücke ausgewertet!

Falls Func1 niemals aufgerufen werden soll, lass es weg ;)


Boldar - Sa 06.12.08 01:47

Nein, das Stimmt nicht, siehe oben.


platzwart - Sa 06.12.08 01:50

k, aber standardmäßig ;)


Boldar - Sa 06.12.08 01:53

Standartmäßig wird der Ausdruck nicht weiter geprüft, also ist Standartmäßig die Checkbox deaktiviert.
Demnach würde da


Delphi-Quelltext
1:
2:
3:
repeat
...
until (True) or (Func1);


func1 NIE ausgeführt!!


WeBsPaCe - Sa 06.12.08 01:55

Hey, super!

Vielen Dank für die Antworten! :-)


Delphi-Quelltext
1:
2:
3:
4:
repeat
...
if True then Break;
until Func1;

Das hilft mir, unabhängig vom Häkchen (da verlass ich mich nicht so gerne drauf, kann irgendwann mal stundenlanges Suchen bedeuten... *g*)

Danke nochmal,
mfG,
WeBBy


Boldar - Sa 06.12.08 01:57

Das heisst, dass func1 nie ausgeführt wird und die Schleife nur einmal durchlaufen wird, da Code Hinter

Delphi-Quelltext
1:
if true then                    


Logischerweise immer ausgeführt wird...


WeBsPaCe - Sa 06.12.08 02:00

:lol:

...jo... ;-) Sinn macht das so keinen... Im Programm ist true dann schon ne Variable, keine Angst. *g*

Btw: so was richtig BEDINGUNGSLOSES hat doch was, oder?... *rrrrrrrrrr* 8)


jaenicke - Sa 06.12.08 02:27

user profile iconWeBsPaCe hat folgendes geschrieben Zum zitierten Posting springen:
Das hilft mir, unabhängig vom Häkchen (da verlass ich mich nicht so gerne drauf, kann irgendwann mal stundenlanges Suchen bedeuten... *g*)
Niemand zwingt dich dich darauf zu verlassen. Dort kann man es projektweit einstellen, unabhängig von dieser Einstellung kannst du es aber auch direkt beim entsprechenden Code per Compilerdirektive einstellen.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure TFormX.ButtonXClick(Sender: TObject);

  function a1: Boolean;
  begin
    MemoX.Lines.Add('a1');
    Result := True;
  end;

  function a2: Boolean;
  begin
    MemoX.Lines.Add('a2');
    Result := True;
  end;

begin
{$B-}
  if a1 or a2 then
    MemoX.Lines.Add('---');
{$B+}
  if a1 or a2 then
    MemoX.Lines.Add('---');
end;
Die Ausgabe wird sein:

Quelltext
1:
2:
3:
4:
5:
a1
---
a1
a2
---
Unabhängig von der Projekteinstellung.


dummzeuch - Sa 06.12.08 11:24

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
unabhängig von dieser Einstellung kannst du es aber auch direkt beim entsprechenden Code per Compilerdirektive einstellen.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
begin
{$B-}
  if a1 or a2 then
    MemoX.Lines.Add('---');
{$B+}
  if a1 or a2 then
    MemoX.Lines.Add('---');
end;


Aber Vorsicht damit: Nach {$B+} ist dann die komplette Auswertung *eingeschaltet*, auch wenn sie vorher in den Projektoptionen ausgeschaltet war. Das kann dann dazu fuehren, dass spaeterer Code nicht so funktioniert wie erwartet.

Solche Einstellungen sollte man nicht leichtfertig aendern. Wenn man es braucht, sollte man sie lieber komplett fuer eine Unit setzen:

Delphi-Quelltext
1:
2:
unit bla;
{$B-}


Zugegebenermassen verlasse ich mich fast immer darauf, dass diese Option ausgeschaltet ist. Das ist evtl. eine schlechte Angewohnheit...

twm


Tilman - Sa 06.12.08 12:35

@dummzeuch: versteh ich nicht. Wenn man für die ganze Unit ausschaltet ist die Gefahr, es zu übersehen, doch viel größer als wenn der Compilerschalter genau an der Anweisung steht wo das unerwartete Verhalten dann später auftritt :gruebel:


jaenicke - Sa 06.12.08 13:01

Das war jetzt ja nur ein Beispiel, ich selbst schalte es nach dem Einschalten immer wieder aus, damit nicht mehr Code als nötig irgendwo ausgeführt wird.

Wenn ich es irgendwo an oder aus brauche, dann setze ich das explizit vor diesem Code mit entsprechendem Kommentar und Eintrag in der Dokumentation, da gibt es kein unerwartetes Verhalten. Nicht setzen tue ich es nur dort wo es (außer was die Performance angeht) egal ist.


WeBsPaCe - Sa 06.12.08 13:30

Hi,

das klingt eigentlich auch ziemlich clever... Hat nur den Nachteil, dass man sich ja dann auch wieder merken muss, was {$B-} bedeutet...

Zuviel für meinen Kopf. *g*

Danke trotzdem, wusste doch, dass da wieder interessantes Zeugs dabei rauskommt. :-D

MfG,
WeBBy


jaenicke - Sa 06.12.08 13:32

user profile iconWeBsPaCe hat folgendes geschrieben Zum zitierten Posting springen:
Hat nur den Nachteil, dass man sich ja dann auch wieder merken muss, was {$B-} bedeutet...
Dann kommentierst du deinen Code schlecht. Sowas kommt als Kommentar dazu bei mir, denn manchmal bin ich mir auch nicht bei jedem Schalter sicher was er heißt. Du kannst ja auch die lange Form BOOLEVAL verwenden ;-).

// EDIT:
Zudem musst du ja auch dazu schreiben im Komentar, dass man sich darauf verlassen kann, dass etwas nicht ausgeführt wird, etc., sonst ist der Code später ohnehin kaum lesbar.


WeBsPaCe - Mi 10.12.08 22:43

Tach.

Doch noch ne Frage, allerdings steht die auch schon im Titel, deswegen kein neuer Thread: liest Delphi das von immer links nach rechts, oder auch mal durcheinander?

Mal ein hübsches Beispiel:

Delphi-Quelltext
1:
2:
3:
if (Application.MessageBox('Traust du dich?', '', 4+48) = 6)
and (Application.MessageBox('Bist du dir sicher?', '', 4+48) = 6)
then ShowMessage('Du bist wirklich tapfer...');


Wäre ja wichtig, dass die eine Frage immer vor der anderen gestellt wird, sonst macht die eine keinen Sinn...

Wisst ihr da auch was?

MfG,
WeBBy


mkinzler - Mi 10.12.08 22:46

Er fängt links an (ausser es wäre geklammert) und wenn , wie in deinem Fall der erste Ausdruck fasch ist, hört er auf, weil der gesammte Ausdruck nicht mehr wahr werden kann!


jaenicke - Mi 10.12.08 22:54

user profile iconmkinzler hat folgendes geschrieben Zum zitierten Posting springen:
Er fängt links an (ausser es wäre geklammert)
Richtig, das ist immer so, darauf kann man sich verlassen.

user profile iconmkinzler hat folgendes geschrieben Zum zitierten Posting springen:
und wenn , wie in deinem Fall der erste Ausdruck fasch ist, hört er auf, weil der gesammte Ausdruck nicht mehr wahr werden kann!
Vorausgesetzt das ist so eingestellt und nicht die vollständige Auswertung aktiviert. (Das wurde ja bereits oben erwähnt.)


WeBsPaCe - Mi 10.12.08 23:13

Tach.

Danke, wo kann man sowas nur nachschlagen...?! :?

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconmkinzler hat folgendes geschrieben Zum zitierten Posting springen:
und wenn , wie in deinem Fall der erste Ausdruck fasch ist, hört er auf, weil der gesammte Ausdruck nicht mehr wahr werden kann!
Vorausgesetzt das ist so eingestellt und nicht die vollständige Auswertung aktiviert. (Das wurde ja bereits oben erwähnt.)

Gib's ihm! :mrgreen:

Vielen Dank ihr beiden!!! :wink:

MfG,
WeBBy


jaenicke - Mi 10.12.08 23:34

user profile iconWeBsPaCe hat folgendes geschrieben Zum zitierten Posting springen:
Danke, wo kann man sowas nur nachschlagen...?! :?
In der Hilfe ;-).
Schau mal unter dem Stichwort "Boolesche Operatoren" --> "Operatoren" etwas weiter unten unter "Vollständige Auswertung und Kurzschlussverfahren im Vergleich".
Hilfe zu Delphi 2009 hat folgendes geschrieben:
Der Compiler unterstützt zwei Auswertungsmodi für die Operatoren and und or: die vollständige Auswertung und das Kurzschlussverfahren. Bei der vollständigen Auswertung werden alle Operanden eines and- oder or-Ausdrucks auch dann ausgewertet, wenn das Resultat des gesamten Ausdrucks bereits feststeht. Das Kurzschlussverfahren geht streng von links nach rechts vor und wird beendet, sobald das Ergebnis des gesamten Ausdrucks feststeht.
[...]
Und so weiter, das wird da noch genauer beschrieben, auch die Compilerdirektive.
Der Link für die Hilfe zu Delphi 2009:
ms-help://embarcadero.rs2009/devcommon/expressions_xml.html
bei 2006 lautet er:
ms-help://borland.bds4/bds4ref/html/Expressions.htm#BooleanOps

Ansonsten findet man im Internet einiges, und wenn ich dann was lese, dann merke ich mir das auch.
Ich schaue mir auch mal den Assemblercode an, den Delphi erzeugt. Das zeigt auch schon einiges.

Es gibt auch Newsgroups mit interessanten Diskussionen.

Vielleicht interessiert dich ja dies: ;-)
http://www.delphi-treff.de/backstage/interna/