| Autor |
Beitrag |
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Di 20.05.08 23:29
Hallo Leute!
Angeregt durch eine andere Diskussion ( www.delphi-forum.de/viewtopic.php?t=82728), habe ich mich mal damit beschäftigt, was passiert, wenn man boolsche Variablen (also tatsächlich das reine boolean, nicht ByteBool, WordBool, LongBool) per Vergleich abfragt, so z.B.
Delphi-Quelltext 1: 2: 3:
| var a: boolean; begin if a=true then... |
statt einfacher:
Delphi-Quelltext 1: 2: 3:
| var a: boolean; begin if a then... |
Erstaunt nahm ich zur Kenntnis, daß "if a then" sicher reagiert, dazu im Gegensatz "if a=true then" nicht, auch dann nicht, wenn a tatsächlich den Wert true besitzt.
Bis dato glaubte ich, daß dieses überflüssige Vergleichen bzw. vergleichende Prüfen nur redundant, also "unsauber" ist, aber nicht existentiell (anscheinend aber in manchen Fällen doch). Weiß jemand genaueres?
Außerdem hielte ich es für angebracht, daß der Compiler wenigstens einen Hinweis auf das Prüfen boolscher Variablen gäbe, aber das ist ein anderes Thema.
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 20.05.08 23:53
|
|
Delphi-Laie 
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Di 20.05.08 23:59
Oh jippie, Antwort kam schneller, als die Polizei erlaubt - herzlichsten Dank!!
|
|
oldmax
      
Beiträge: 380
D3 Prof, D4 Prof
|
Verfasst: Mi 21.05.08 09:49
Hi
Nun zur Verwirrung will ich mich denn auch mal äußern, da mir die Erklärung von Michael noch nicht ganz schlüssig erscheint.
Delphi-Quelltext 1: 2: 3: 4: 5:
| Function Vergleiche(x,y:Irgendwas):Boolean; Begin If x=y then Result:=true else Result:=false; end; |
True ist doch nach der Aussage Konstante -1 und False Konstante 0 also ließe es sich doch abfragen
Delphi-Quelltext 1:
| If Vergleiche(4,6) = True then |
wenn die Logik stimmt....
Vermutlich ist aber True nicht immer Konstant -1, da auch hier eben nicht nur ein Bit, sondern mindestens ein Byte benutzt wird und daher nur der Wert 0 ( alle Bitts =0) eindeutig ist, nicht aber die 255 anderen möglichen Werte. Eine schlüssige Erklärung ist dies aber auch noch nicht, warum das True nicht eindeutig definiert ist.
Gruß oldmax
_________________ Zier dich nich so, ich krieg dich schon....
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mi 21.05.08 10:55
Das Problem tritt doch nur bei undefinierten bool'schen Variablen oder dreckigem Typecasting auf.
Bei sauberer Programmierung sollte bzw. wird(!) eine Abfrage auf (=TRUE) immer das gleiche Ergebnis wie die direkte Auswertung des Terms liefern. Das ist auch logisch, weil dann jeder Boolean-Wert immer genau entweder 'True' oder 'False' ist.
Der Fehler ist: alle Werte <> 0 als 'True' anzunehmen. Das ist so dermaßener Quark, das man sich fragt, wer auf so einen kranke Definition gekommen ist (Borland, ich weiss). Denn das ist doch schon mathematisch Blödsinn: Der Datentyp 'bool' hat genau zwei Werte. True oder False. Wie True bzw. False intern dargestellt werden, interessiert mich nicht.
Hier ist das Typecasten der Casus Knactus: Vergleichen wir mal das Verhalten einer Enumeration mit dem Datentyp Bool:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| Type TBoolean = (bFalse, bTrue);
Var x : TBoolean; y : Boolean;
Begin x := TBoolean(123); y := Boolean(123); If y=True Then Writeln ('Das hier wirst Du nie sehen'); |
Hier haben wir einen echten Designfehler von Delphi, denn es ist nun wirklich so, das True<>True ist, bzw. die Aussage True=True nicht stimmt bzw. ist der Wert 'True' nicht eindeutig. Und das soll ein Datentyp sein, mit dem man logisch rechnen kann?
Ich meine, das die 'Wahrheit' (True) mehrere Facetten haben kann, bzw. sich Wahrheiten ausschließen können, ist zwar philosophisch interessant, aber nicht mathematisch. Insofern hätte Borland den Datentyp 'Boolean' in 'PhilosophicBoolean' umbenennen sollen. Dann gäbe es nämlich die reine Wahrheit (True), sowie beliebig viele andere Wahrheiten (<>False)...
_________________ Na denn, dann. Bis dann, denn.
|
|
hazard999
      
Beiträge: 162
Win XP SP2
VS 2010 Ultimate, CC.Net, Unity, Pex, Moles, DevExpress eXpress App
|
Verfasst: Mi 21.05.08 11:14
Nur als kleiner Hinweis:
Wie wärs mit:
Delphi-Quelltext 1: 2: 3: 4:
| Function Vergleiche(x,y:Irgendwas):Boolean; Begin Result := (x = y); end; |
_________________ MOV EAX, Result;MOV BYTE PTR [EAX], $B9;MOV ECX, M.Data;MOV DWORD PTR [EAX+$1], ECX;MOV BYTE PTR [EAX+$5], $5A;MOV BYTE PTR [EAX+$6], $51;MOV BYTE PTR [EAX+$7], $52;MOV BYTE PTR [EAX+$8], $B9;MOV ECX, M.Code;MOV DWORD PTR [EAX+$9], ECX
|
|
baka0815
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Mi 21.05.08 14:48
Die Geschichte von "true := <> 0" kommt aus der C-Welt.
Da es dort keine boolschen Werte gibt, sondern nur Zahlen und Zeichen, wurde das halt so definiert.
Ist zum Auswerten von Zahlen auch gar nicht so blöd:
Quelltext 1:
| if (testFunktion()) then |
funktioniert so eben auch, wenn testFunktion einen numerischen Wert zurück liefert.
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mi 21.05.08 15:08
Jupp, genau und bei API-Funktionen mus True eben nicht immer unbedingt -1 sein.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mi 21.05.08 15:29
Der Grund ist sonnenklar, aber Delphi/Pascal als typenstrenge Sprache bzw. der Compiler und die Delphi-Sprachdefinition hätte hier (also beim Typecasten) etwas mehr Magic einbauen müssen. Das C das locker sieht, ist eh klar. C sieht ALLES locker.
_________________ Na denn, dann. Bis dann, denn.
|
|
jaenicke
      
Beiträge: 19341
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 21.05.08 15:35
Warum? Ich finde es weder schön noch sinnvoll überhaupt mit true oder false zu vergleichen, ich habe ja schon einen boolschen Wert. Dass da jemand überhaupt auf die idee kommen könnte, darauf muss man erstmal kommen. Und durch Compiler-Magic dort herumzubasteln könnte vielleicht auch andere Probleme bringen, wenn das Verhalten erwünscht bzw. notwendig ist wegen einer API...
Grundsätzlich denke ich jedenfalls, dass das Problem eher von schlechten Anfängerseiten oder Lehrern herrührt, die so etwas überhaupt machen. Ich wäre nie auf die Idee gekommen das so zu machen, weil ich es selbst alles ausprobiert und nur mit der Delphi-Hilfe erarbeitet habe. (Ich hatte kein Internet...)
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mi 21.05.08 16:06
Das Problem ist, das für alle boolschen werte gelten muss : True = True.
Hier haben wir: Boolean(1) = True und Boolean (2) = True, aber Boolean(1)<>Boolean(2), ergo True<>True. Das erkläre mal einem Mathematiker.
Das ist die Grütze, bzw. der ästhetische Designfehler in Delphi. Das man nicht auf '=true' vergleichen sollte, ist imho logisch.
_________________ Na denn, dann. Bis dann, denn.
|
|
jaenicke
      
Beiträge: 19341
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 21.05.08 16:09
Das Problem: Delphi müsste dann überprüfen ob der Wert nicht dem Standardtrue entspricht und den Wert darauf setzen. Nur verbraucht das Rechenzeit.
Und bei sauberer Programmierung hatte ich noch nie ein Problem damit, auch nicht, wenn API-Funktionen nicht unbedingt das Standardtrue geliefert haben, deshalb hielte ich es für falsch zusätzlichen Code einzubauen für diese Prüfung.
|
|
baka0815
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Mi 21.05.08 16:27
Einfach immer "<> false" prüfen 
|
|
jaenicke
      
Beiträge: 19341
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 21.05.08 16:29
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Mi 21.05.08 16:33
_________________ Markus Kinzler.
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Mi 21.05.08 20:58
Hi,
Ich glaube das <> false war mit einem lächelnden Auge
Als ich mich mit der absoluten Asymmetrie des Boolean-Typs beschäftigt habe, konnte ich mir das eigentlich nur so erklären: Vergleiche von Zahlen müssen ja vom Prozessor umgesetzt werden.
Nun könnten diese Vergleiche durch bitweise Verfahren(Xor für ungleich, etc.) ablaufen. In diesem Fall wäre es günstig, wenn man direkt das Ergebnis dieser Bitweisen Operation ausgeben könnte, statt es wiederum in zwei konstante Werte umzucasten.
Das sage ich jetzt als Laie, der sich nur mal Gedanken über eine potentiell doch vorhandene Logik gemacht hat.
Natürlich ist Kompatiblität bereits Grund genug: Wenn C Boolean so umsetzt, ist der Delphi-Datentyp kompatibel zu C(Was man aber imho nur z.B. beim C-Auslesen aus einer Datei, die mit einem Delphi-basierten Programm geschrieben wurde, gebrauchen kann).
mfG,
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
jaenicke
      
Beiträge: 19341
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 22.05.08 09:01
Hidden hat folgendes geschrieben: | Ich glaube das <> false war mit einem lächelnden Auge  |
Das habe ich gehofft und deshalb auch nicht weiter was dazu geschrieben, aber ich finds halt nicht gut, sowas zu schreiben, was ja auch andere lesen, denen nicht klar ist, dass das Blödsinn ist. Deshalb die Smileys  .
Hidden hat folgendes geschrieben: | | Natürlich ist Kompatiblität bereits Grund genug: Wenn C Boolean so umsetzt, ist der Delphi-Datentyp kompatibel zu C(Was man aber imho nur z.B. beim C-Auslesen aus einer Datei, die mit einem Delphi-basierten Programm geschrieben wurde, gebrauchen kann). |
Nein, der Grund sind vor allem die bereits erwähnten API-Aufrufe  . Denn die gehen von diesem boolschen Verhalten aus, da die Windows API (genau wie andere APIs) in C geschrieben ist.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Do 22.05.08 11:19
Eigentlich wäre das doch einfach: Wir definieren: False = 0, True = 1.
Typecasting wäre 1 Pikosekunde langsamer, weil nun der Code 'Wenn <> 0 dann 1' eingefügt wird (damit das Typecasting auf Boolean wieder genau einen(!) der beiden möglichen Werte liefert).
So kenn ich das übrigens aus anderen Sprachen und Pascal-Derivaten.
Aber neeee, Delphi muss ja immer zu C(++) schielen  Ach, was solls. Ich programmier einfach sauber und ordendlich, dann ist mir das doch Schnurz. 
_________________ Na denn, dann. Bis dann, denn.
|
|
baka0815
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Mi 28.05.08 15:00
Hidden hat folgendes geschrieben: | Hi,
Ich glaube das <> false war mit einem lächelnden Auge  |
Japp, war es. Ich dachte der Smiley dahinter würde ausreichen.
Warum genau man einen boolschen Ausdruck nochmal auf solchen prüfen sollte, ist mir jedoch auch nicht klar. Sinn macht sowas nur, wenn man einen undefinierten Zustand braucht, also "true", "false" und "undefinded" (bzw. FileNotFound falls das wer von DailyWTF kennt  ).
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Mo 02.06.08 18:24
Hey, siehste... die hatten damals schon Quantencomputer im Auge
Stimmt aber eigentlich... könnte man TriState Logik ganz einfach mit implementieren...
Delphi-Quelltext 1:
| if a and not (a=True) then |
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
|