Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Warum ist ein Boolean so groß? (https://www.delphipraxis.net/55716-warum-ist-ein-boolean-so-gross.html)

Eichhoernchen 25. Okt 2005 22:06


Warum ist ein Boolean so groß?
 
Hab gerade mal im Wikipedia über Object Pascal gelesen.
Zitat:

Zitat von Wikipedi
ByteBool / Boolean 1 Byte true oder false boolescher Wert
WordBool 2 Byte true oder false boolescher Wert
LongBool 4 Byte true oder false boolescher Wert


Wozu ist es nötig das nen Boolean 1 byte groß ist?

Man muss doch nur 2 zustände darstellen, TRUE und FALSE also da würd doch sogar nen bit reichen?!

warum gibt es auch 4 byte große booleans und wo ist der Unterschied?

Tubos 25. Okt 2005 22:12

Re: Warum ist ein Boolean so groß?
 
Man kann in einem PC nur jedes Byte adressieren.

Zitat:

warum gibt es auch 4 byte große booleans und wo ist der Unterschied?
2 und 4 Byte große Bools wird es deshalb geben, damit die genau 2 oder 4 Byte groß sind.
Hoppla, erst nachdem ich den Satz geschrieben habe bin ich draufgekommen dass das keine wirkliche Begründung ist. Bevor ich vage Vermutungen äußere darf den Teil der Frage jemand anderer beantworten :zwinker:

ripper8472 25. Okt 2005 22:12

Re: Warum ist ein Boolean so groß?
 
weil du nur byteweise addressieren kannst!

was widebool fuern zweck hat, entzieht sich meiner logik... tja, delphi eben

Oxmyx 25. Okt 2005 22:19

Re: Warum ist ein Boolean so groß?
 
Einfach gesagt: 32 Bit große Typen werden von der CPU schneller verarbeitet.

Aus genau diesem Grund richtet Delphi die Strukturmitglieder standardmäßig auch auf 4 Byte aus:
Delphi-Quellcode:
  TTest = record
    a: Byte;
    b: Integer;
  end;
belegt standardmäßig nicht etwa 5 Byte, wie man vermuten würde, sondern 8 Byte, weil das einzelne Byte auf 32 Bit ausgerichtet wird.

Eichhoernchen 25. Okt 2005 22:30

Re: Warum ist ein Boolean so groß?
 
ahwas, okay macht Sinn das mit den Adresssierungen von Bytes, wäre ja auch ganz schön durcheinander wenn es bits wären die adressiert werden. Hmm und das mit den größeren scheint dann ja nur "geschwindigkeits"vorteile zu bringen?!

Naja also kann nen 4 byte bool auch nicht mehr als nen 2 byte großer, das reicht mir schon,

Aber wird der Delphi kompiler nicht ehh dann aus jedem 1 byte bool nen 4 byte(32bit) bool machen, wenn die CPU das besser verarbeiten kann? wie schaut es bei 64 bit prozessoren aus? oder hat das jetzt gar nix damit zu tun? Ich kenne mich in dem Bereich nicht so gut aus. wäre da nen 8byte bool besser als nen 4er?


Die hab ja einen an der Waffel bei Borland ;) 4 byte Bools, wo kommen wir noch hin....



Eichhoernchen

himitsu 25. Okt 2005 22:42

Re: Warum ist ein Boolean so groß?
 
Man kann Booleans auch Incrementieren und Decrementieren.

Delphi-Quellcode:
Var B: Boolean/ByteBool/WideBool/LongBool; // geht bei allen

Inc(B);
Dec(B);
Die Booleans sind ja so definiert:
Code:
True:  B <> 0
False: B = 0
Und die Standard-Konstanten:
Code:
True = 1
False = 0
Also:
Delphi-Quellcode:
Var B: Boolean/ByteBool;

B := False; // 0 > False
Inc(B);     // 1 > True
Inc(B);     // 2 > True
Dec(B);     // 1 > True
Dec(B);     // 0 > False
Dec(B);     // 255 > True
Man kann es also z.B. zum Sperren von irgendwas verwenden, wenn z.B. dieses von mehreren Prozessen gesperrt werden soll und nur wieder freigegeben soll, wenn es auch wieder von allen Prozessen freigegeben wurde.
Delphi-Quellcode:
Var gesperrt: ByteBool/Boolean;

gesperrt := False; // 0: initialasieren = freigegeben
Inc(gesperrt);     // 1: sperren  = gesperrt
Inc(gesperrt);     // 2: sperren  = gesperrt
Dec(gesperrt);     // 1: freigeben = gesperrt
Inc(gesperrt);     // 2: sperren  = gesperrt
Dec(gesperrt);     // 1: freigeben = gesperrt
Dec(gesperrt);     // 0: freigeben = freigegeben
wobei die Richtung in diesem Fall eigentlich sogar egal ist:
Delphi-Quellcode:
gesperrt := False; // 0:  initialasieren = freigegeben
Dec(gesperrt);     // 255: sperren  = gesperrt
Dec(gesperrt);     // 254: sperren  = gesperrt
Inc(gesperrt);     // 255: freigeben = gesperrt
Dec(gesperrt);     // 254: sperren  = gesperrt
Inc(gesperrt);     // 255: freigeben = gesperrt
Inc(gesperrt);     // 0:  freigeben = freigegeben
Und abfragen kann man dieses ja dann ganz einfach so:
Delphi-Quellcode:
If gesperrt Then ...

[add]
PS:

in Delphi: Boolean = ByteBool
und in Windows/C++: BOOL = LongBool

die WinAPI-Funktionen verwenden alle das LongBool (32-Bit)


[add2]
Ach ja, geschwindigkeitsvorteil gibt es auch nicht immer.

z.B. dürfte
Delphi-Quellcode:
Var B: Boolean/ByteBool;
B := True;
schneller sein als
Delphi-Quellcode:
Var B: LongBool;
B := True;
(wenn ihr euch mal den Befehl in ASM anseht, dann werdet ihr merken, daß der 32-Bit-Befehl größer ist)

Mystic 25. Okt 2005 22:55

Re: Warum ist ein Boolean so groß?
 
Zitat:

Zitat von Oxmyx
Einfach gesagt: 32 Bit große Typen werden von der CPU schneller verarbeitet.

Aus genau diesem Grund richtet Delphi die Strukturmitglieder standardmäßig auch auf 4 Byte aus:
Delphi-Quellcode:
  TTest = record
    a: Byte;
    b: Integer;
  end;
belegt standardmäßig nicht etwa 5 Byte, wie man vermuten würde, sondern 8 Byte, weil das einzelne Byte auf 32 Bit ausgerichtet wird.

Und packed record hebt die Ausrichtung wieder auf:
Delphi-Quellcode:
  TTest = packed record
    a: Byte;
    b: Integer;
  end;
Und sorgt so dafür dass dieser record auch nur 5 Byte groß ist.

SMO 26. Okt 2005 00:38

Re: Warum ist ein Boolean so groß?
 
Zitat:

Zitat von Oxmyx
Einfach gesagt: 32 Bit große Typen werden von der CPU schneller verarbeitet.

Aus genau diesem Grund richtet Delphi die Strukturmitglieder standardmäßig auch auf 4 Byte aus:
Delphi-Quellcode:
  TTest = record
    a: Byte;
    b: Integer;
  end;
belegt standardmäßig nicht etwa 5 Byte, wie man vermuten würde, sondern 8 Byte, weil das einzelne Byte auf 32 Bit ausgerichtet wird.

Das stimmt so nicht ganz. Nicht das Byte "a" wird ausgerichtet, sondern der Integer "b". Delphi richtet die Felder eines nicht-gepackten Records so aus, dass ein Feld der Größe X Bytes an einer Speicheradresse beginnt, die ohne Rest durch X teilbar ist (für X = 1, 2, 4, 8 ). Wandeln wir mal dein Beispiel etwas ab:
Delphi-Quellcode:
  TTest = record
    a: Byte;
    b: Int64;
  end;
Delphi fügt jetzt nicht 3 Bytes sondern 7 Bytes hinter "a" ein, damit "b", welches 8 Bytes groß ist, an einer Speicheradresse beginnt, die durch 8 teilbar ist. SizeOf(TTest) wäre somit nicht mehr 8 sondern 16.




Zitat:

Zitat von Eichhoernchen
Hmm und das mit den größeren scheint dann ja nur "geschwindigkeits"vorteile zu bringen?!

Aber wird der Delphi kompiler nicht ehh dann aus jedem 1 byte bool nen 4 byte(32bit) bool machen, wenn die CPU das besser verarbeiten kann? wie schaut es bei 64 bit prozessoren aus? oder hat das jetzt gar nix damit zu tun? Ich kenne mich in dem Bereich nicht so gut aus. wäre da nen 8byte bool besser als nen 4er?

Im Falle der Ausrichtung wie oben erwähnt, ja. Wenn eine Variable, die mehrere Bytes groß ist, nicht richtig ausgerichtet ist (z.B. ein 16 Bit Word, das an einer ungeraden Speicheradresse beginnt), muss die CPU unter Umständen zwei Speicherzugriffe tätigen, um die Variable einmal zu lesen. Das sollte natürlich vermieden werden.

Was die Größe der Bools betrifft: meines Wissens stimmt es schon, dass Datentypen in der "nativen" Größe einer CPU vorzuziehen sind (wenn man nicht gerade Speicher sparen muss). Eine 8-Byte-Bool Variable könnte also durchaus die beste Wahl auf einer 64 Bit CPU sein. Aber ob z.B. ein LongBool nun in der Praxis (auf einem 32 Bit Prozessor) wirklich schneller ist als ein 8 Bit Boolean, weiß ich nicht (ich zweifle). Sollte jemand mal genau messen. :)

Zitat:

Die hab ja einen an der Waffel bei Borland ;) 4 byte Bools, wo kommen wir noch hin....
Wie himitsu bereits schrieb, das ist nicht auf Borlands Mist gewachsen. ;)




Zitat:

Zitat von himitsu
Die Booleans sind ja so definiert:
Code:
True:  B <> 0
False: B = 0
Und die Standard-Konstanten:
Code:
True = 1
False = 0
in Delphi: Boolean = ByteBool

Ich glaube das stimmt nicht ganz. True = 1 gilt nur für Boolean. Für Byte/Word/LongBool ist True = -1. Es gibt also einen feinen Unterschied zwischen Boolean und ByteBool.
Zum Testen:
Delphi-Quellcode:
procedure BoolTest;
var
  B0: Boolean;
  B1: ByteBool;
  B2: WordBool;
  B3: LongBool;
begin
  B0 := True;
  B1 := True;
  B2 := True;
  B3 := True;
  ShowMessage(Format('B0 = %d'#10'B1 = %d'#10'B2 = %d'#10'B3 = %d',
    [Ord(B0), Ord(B1), Ord(B2), Ord(B3)]));
end;

himitsu 26. Okt 2005 01:27

Re: Warum ist ein Boolean so groß?
 
Könntest recht haben ... laut MS sind bei TRUE alle Bit's gesetzt ... sowas kommt davon, wenn man zuviel mit den Borland's eigenen Typen rummacht -.-''
(muß i glei ma gucken, ob'sch das och überall richtig gemacht hab)

Blöd nur, wenn man diese Tatsache zwar irgendwie im Hinterkopf hat, das einam aber dennoch nicht wirklich auffällt, aber dank dir ist's mir jetzt wie Schuppen auf den Haaren gefallen :mrgreen:

Robert Marquardt 26. Okt 2005 05:08

Re: Warum ist ein Boolean so groß?
 
Ein Byte ist die kleinste von jedem Prozessor zu adressierende Einheit.
Es hat also keinen Zweck Boolean kleiner zu machen. Man koente es auf einigen Prozessoren nicht mehr adressieren.

WordBool und LongBool sind Typen zur Unterstuetzung des Windows API.
In C gibt es keinen Boolean Typ. Dort gilt alles ungleich Null als True und Null als False.
Entsprechend liefern viele Win32-Funktionen faktisch einen LongBool.

himitsu 26. Okt 2005 05:30

Re: Warum ist ein Boolean so groß?
 
Ach, daher haben die C-Header, worauf Delphi ja anscheinend aufgebaut ist, Integer/Cardinal, obwohl das Win32-SDK was von BOOL(LongBool) sagt.
Und ich dachte schon die haben sich verlesen -.-''

alzaimar 26. Okt 2005 07:00

Re: Warum ist ein Boolean so groß?
 
@himitsu: Das ist ja blasphemisch, was Du mit den Booleans anstellst (inc/dec) :zwinker: Das funktioniert? Cool, ehrlich. Aber ich würde das nicht in meinen Code schreiben, weil es durchaus mal sein kann, das Borland das nicht mehr unterstützt. Und dann suchst Du dir einen Wolf.

Robert Marquardt 26. Okt 2005 07:15

Re: Warum ist ein Boolean so groß?
 
Ein Boolean ist ein ordinaler Datentyp mit Succ(False) = True und Pred(True) = False sowie Ord(False) = 0 und Ord(True) = 1. Das ist Pascal.
Inc() und Dec() auf einem Boolean sind wirklich ein wenig dubios. Auf einem ByteBool, WordBool oder LongBool hingegen nicht, da dies Zahlentypen sind.

Muetze1 26. Okt 2005 07:28

Re: Warum ist ein Boolean so groß?
 
Zitat:

Zitat von Robert Marquardt
Ein Boolean ist ein ordinaler Datentyp mit Succ(False) = True und Pred(True) = False sowie Ord(False) = 0 und Ord(True) = 1. Das ist Pascal.
Inc() und Dec() auf einem Boolean sind wirklich ein wenig dubios. Auf einem ByteBool, WordBool oder LongBool hingegen nicht, da dies Zahlentypen sind.

Und genau deshalb ergibt Ord(Boolean(True)) immer 1, obwohl intern Borland auch hier mit -1 als Wert für True arbeitet.

Robert Marquardt 26. Okt 2005 09:09

Re: Warum ist ein Boolean so groß?
 
Zitat:

Zitat von Muetze1
Und genau deshalb ergibt Ord(Boolean(True)) immer 1

Das ist ein unsinniger Ausdruck. True ist bereits vom Typ Boolean. Eine Umtypung ist nicht noetig.

Mal genauer:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var
  B: Boolean;
  BB: ByteBool;
  WB: WordBool;
  LB: LongBool;
begin
  B := True;
  BB := B;
  WB := B;
  LB := B;
  ShowMessageFmt('%d %d %d %d', [Ord(B), Ord(BB), Ord(WB), Ord(LB)]);
end;
Das ergibt "1 -1 -1 -1".
Damit ist klar das ByteBool, WordBool und LongBool vorzeichenbehaftet sind (trotz ihres Namens).
Bei der Zuweisung von B wird eine Signextension vorgenommen, obwohl Boolean formal vorzeichenlos ist.
Intern wird fuer Boolean True auch definitiv 1 genommen. Aendert man naemlich Ord(B) im oben gezeigten Beispiel in Byte(B),
so wird immer noch "1" ausgegeben.
Der Grund fuer -1 als True in ByteBool etc ist Visual Basic das mit 0 und -1 in einem Long operiert.

himitsu 26. Okt 2005 12:53

Re: Warum ist ein Boolean so groß?
 
Zitat:

Zitat von alzaimar
@himitsu: Das ist ja blasphemisch, was Du mit den Booleans anstellst (inc/dec) :zwinker: Das funktioniert? Cool, ehrlich. Aber ich würde das nicht in meinen Code schreiben, weil es durchaus mal sein kann, das Borland das nicht mehr unterstützt. Und dann suchst Du dir einen Wolf.

Also da brauchst du/ihr wohl keine Bedenken haben ... kennt ihr z.B. die Klasse TCanvas?, dort wird inern sowas gemacht (um das Canvas zu sperren), wenn ich mich nicht irre (hab hier kein Delphi und daheim ist's im Moment auch nicht installiert, also kann ich da nicht nochmal nachsehen, aber ich glaub das mal gesehn zu haben ^^)

Also zumindestens bei ByteBool/WordBool/LongBool, bei Boolean scheint es zwar anders zu sein, aber da es sich dort auch um ein Byte handelt (was sih wohl auch nicht ändern wird), sollte es dort auch so bleiben ... jedenfalls wird ja immer (wenn ordentlich programmiert wurde) auf =0 und <>0 geprüft.

Muetze1 26. Okt 2005 13:02

Re: Warum ist ein Boolean so groß?
 
Zitat:

Zitat von Robert Marquardt
Zitat:

Zitat von Muetze1
Und genau deshalb ergibt Ord(Boolean(True)) immer 1

Das ist ein unsinniger Ausdruck. True ist bereits vom Typ Boolean. Eine Umtypung ist nicht noetig.

Das war kein Quellcode, dann hätte ich ihn entsprechend gekennzeichnet - das war Pseudocode. Ich wollte mit dem Boolean() den Typ nochmal explizit hervorheben auf den ich mich mit meiner Aussage beziehe.

Und bei dem Byte() Typecast wird afaik auch trotzdem die Umwandlung wie bei Ord() genommen intern. Ich glaube das Borland das intern so gebastelt hatte (Compiler Magic).

Khabarakh 26. Okt 2005 13:08

Re: Warum ist ein Boolean so groß?
 
Zitat:

Zitat von himitsu
Also da brauchst du/ihr wohl keine Bedenken haben ... kennt ihr z.B. die Klasse TCanvas?, dort wird inern sowas gemacht (um das Canvas zu sperren), wenn ich mich nicht irre (hab hier kein Delphi und daheim ist's im Moment auch nicht installiert, also kann ich da nicht nochmal nachsehen, aber ich glaub das mal gesehn zu haben ^^)

Wenn du LockCount meinst: ist ein Integer :wink: .

Richtig lustig wird dann so etwas:
Delphi-Quellcode:
var
  b: Boolean;
begin
  b := Boolean(2);

  if b then
    Writeln('1');

  if b = true then
    Writeln('2');

  Readln;
end.
Ich denke, ihr könnte euch die Ausgabe vorstellen :mrgreen: .

Olli 26. Okt 2005 13:13

Re: Warum ist ein Boolean so groß?
 
Gegenfrage:
Warum ist das menschliche Gehirn zu einem hohen Prozentsatz ungenutzt?


Ist doch redundant. Laßt es uns rausschnippeln. Also sorry, ich verstehe nicht wo das Problem ist, zumal schon die erste Antwort völlig korrekt war (Tubos). Auch der spätere Einwand, daß je nach Adressierungsmodus des Prozessors auch 32bit oder neuerdings 64bit schneller sein können war völlig korrekt (Oxmyx).

SMO 26. Okt 2005 17:20

Re: Warum ist ein Boolean so groß?
 
Zitat:

Zitat von Olli
Gegenfrage:
Warum ist das menschliche Gehirn zu einem hohen Prozentsatz ungenutzt?
Ist doch redundant. Laßt es uns rausschnippeln.

Meinst du das ernst? Ich hoffe nicht (sorry, mein Ironiedetektor ist gerade defekt :)). Das ist ein doofer alter Mythos. Wir benutzen 100% unseres Gehirns, wenn auch nicht gleichzeitig (CPUs sind ja auch nicht immer zu 100% benutzt/ausgelastet ;)). Siehe z.B. hier (Deutsch) oder hier (Englisch).

Zitat:

Also sorry, ich verstehe nicht wo das Problem ist, zumal schon die erste Antwort völlig korrekt war (Tubos). Auch der spätere Einwand, daß je nach Adressierungsmodus des Prozessors auch 32bit oder neuerdings 64bit schneller sein können war völlig korrekt (Oxmyx).
Ich glaube nicht, dass es hier ein "Problem" gibt, ich finde diese Diskussion interessant. Oxmyx' Aussage über die Ausrichtung war inkorrekt, was mich dazu angestoßen hat hier teilzunehmen. Ebenso wie mich deine kühne Aussage dazu verleitet hat, nochmal zu antworten. ;)


@Khabarakh:
Das ist wirklich lustig! Interessanterweise funktioniert dieser "Trick" (Fehler?) nicht mehr bei Byte/Word/LongBool. Der Compiler übersetzt dort "b := ByteBool(2)" direkt zu "b := -1". Aber selbst wenn man b anders auf den Wert 2 zwingt (z.B. "Byte(b) := 2") prüft "b = true" nicht etwa auf =1 oder =-1 sondern korrekt auf <>0.
Zusammengefasst also: Mit Boolean wird nur 1 ausgegeben, mit den anderen Bool-Typen 1 und 2.

Olli 26. Okt 2005 18:02

Re: Warum ist ein Boolean so groß?
 
Zitat:

Zitat von SMO
Meinst du das ernst?

Ja.

Zitat:

Zitat von SMO
Das ist ein doofer alter Mythos. Wir benutzen 100% unseres Gehirns, wenn auch nicht gleichzeitig (CPUs sind ja auch nicht immer zu 100% benutzt/ausgelastet ;)). Siehe z.B. hier (Deutsch) oder hier (Englisch).

Wer's glaubt. Wenn du da eher irgendwelchen Leuten als dir selber glaubst, kann ich auch nix für :zwinker: ... wenn du natürlich alles nutzt, dann gilt dir mein vollster Respekt.

Zitat:

Zitat von SMO
Ich glaube nicht, dass es hier ein "Problem" gibt, ich finde diese Diskussion interessant. Oxmyx' Aussage über die Ausrichtung war inkorrekt, was mich dazu angestoßen hat hier teilzunehmen. Ebenso wie mich deine kühne Aussage dazu verleitet hat, nochmal zu antworten. ;)

Oxmyx' Aussage zum Alignment im Record war falsch, stimmt. Aber die Aussage, daß ausgerichtete Strukturen schneller bearbeitet werden war völlig korrekt.

Oxmyx 26. Okt 2005 18:11

Re: Warum ist ein Boolean so groß?
 
Es war unbedacht formuliert, aber es wusste doch jeder, was ich gemeint hatte.

NicoDE 26. Okt 2005 18:47

Re: Warum ist ein Boolean so groß?
 
Beispiel: Der Rückgabewert der Win32-API-Funktion GetMessage() ist von Borland 1:1 als BOOL(LongBool) übersetzt worden:
Delphi-Quellcode:
function GetMessage(var lpMsg: TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax: UINT): BOOL; stdcall;
Der Grund dafür ist relativ ersichtlich, da die Dokumentation besagt, dass die Funktion bei WM_QUIT 0 zurückgibt und anderfalls einen Wert ungleich 0.

Deshalb sehen viele Nachrichtenschleifen von Fenstern so aus:
Delphi-Quellcode:
while GetMessage(Msg, Wnd, 0, 0) do
begin
  // ...
end;
ExitCode := Msg.wParam;
Allerdings besagt die Dokumentation auch, dass in einem Fehlerfall (z.B. ungültiges Fenster-Handle) -1 zurückgegeben wird. Der Code sollte also 'besser' so aussehen (um eine Endlosschleife im Fehlerfall zu vermeiden):
Delphi-Quellcode:
while True do
  case Longint(GetMessage(Msg, Wnd, 0, 0)) of
    0: // WM_QUIT
      begin
        ExitCode := Msg.wParam;
        Break;
      end;
    -1: // ERROR!
      begin
        ExitCode := 42;
        Break;
      end;
  else
    //...
  end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:10 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz