Is AND-operator short-circuiting in Pascal?
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Is AND-operator short-circuiting in Pascal?
@ m.fuchs
Wenn Du Dir 30 Jahre zu spät Gedanken um boolean short-circuit machst, dann ist das kein Rant, sondern ein trauriges Bild von Dir.
Und dann hätte ich gerne mal ein halbwegs sauber programmiertes Beispiel von Dir, wie man den short-circuit aufs Kreuz legt....
Erstmal um die Grundlagen kümmern. Wie gesagt.
Winni
Wenn Du Dir 30 Jahre zu spät Gedanken um boolean short-circuit machst, dann ist das kein Rant, sondern ein trauriges Bild von Dir.
Und dann hätte ich gerne mal ein halbwegs sauber programmiertes Beispiel von Dir, wie man den short-circuit aufs Kreuz legt....
Erstmal um die Grundlagen kümmern. Wie gesagt.
Winni
-
- Lazarusforum e. V.
- Beiträge: 395
- Registriert: Sa 15. Mai 2010, 13:46
- CPU-Target: 64 bit
- Kontaktdaten:
Re: Is AND-operator short-circuiting in Pascal?
Zur Optimierung: Nehmen wir einen Ausdruck, wie:
Das kann man logisch auch zu einem (a or b) optimieren. Eigentlich würde ich erwarten, dass der Compiler solche Optimierungen auch durchführt. Aber wenn a jetzt ein Funktionsaufruf ist, der im Hintergrund etwas tut, dann würde a bei true zwei mal aufgerufen ohne Optimierung und mit Optimierung nurnoch ein mal...
Um das zu vermeiden, müsste die Optimierung nur dann passieren, wenn im Ausdruck keine Aufrufe passieren. Naja, oder nur solche Aufrufe optimieren, die einen reinen read-only charakter haben. Oft verwenden wir ja properties mit gettern und settern... Ist FPC jetzt schlau genug, in die Tiefe eines getters einzusteigen und zu entscheiden, ob es egal ist, den zwei mal aufzurufen?
Für eine AND-Verknüpfung halte ich short-circuiting schon für sinnvoll. Aber in Javascript kann man auch so brillianten Code creieren, wie den folgenden:
Der ||-Operator kann nicht nur Boolesche Werte vergleichen, sondern nimmt auch ein Object an und dann gilt null als false und alles andere als true. Ein echter, impliziter Typecast findet aber nicht statt, da der Ausdruck im falle "not null" weiterhin das gültige Object für a zurück gibt, statt true
Dass Pascal es mit solchen Konzepten nicht gerade übertreibt, finde ich nicht so schlecht
Code: Alles auswählen
if (a) and (a or b) then ...
Um das zu vermeiden, müsste die Optimierung nur dann passieren, wenn im Ausdruck keine Aufrufe passieren. Naja, oder nur solche Aufrufe optimieren, die einen reinen read-only charakter haben. Oft verwenden wir ja properties mit gettern und settern... Ist FPC jetzt schlau genug, in die Tiefe eines getters einzusteigen und zu entscheiden, ob es egal ist, den zwei mal aufzurufen?
Für eine AND-Verknüpfung halte ich short-circuiting schon für sinnvoll. Aber in Javascript kann man auch so brillianten Code creieren, wie den folgenden:
Code: Alles auswählen
function MyObject () {
}
MyObject.prototype = {
doSomething : function () {
alert('Es tut!');
}
};
function getObject () {
if (Math.random() > 0.5) return new MyObject();
else return null;
}
function die (msg) {
throw new Error(msg);
}
(function () {
var a = getObject() || die("Can't create object!");
a.doSomething();
})();

Dass Pascal es mit solchen Konzepten nicht gerade übertreibt, finde ich nicht so schlecht

- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2809
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: Is AND-operator short-circuiting in Pascal?
Mein DeLorean ist leider gerade in der Werkstatt, sonst würde ich die Diskussion dreißig Jahre früher durchführen.Winni hat geschrieben: Mi 16. Nov 2022, 12:59 Wenn Du Dir 30 Jahre zu spät Gedanken um boolean short-circuit machst, dann ist das kein Rant, sondern ein trauriges Bild von Dir.
Aber kleiner Tipp: wenn dich das hier so nervt - lies und schreibe einfach nicht mit. Das hat auch für den Rest den Vorteil dass man deinen rüden Umgangston nicht ertragen muss.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
-
- Beiträge: 955
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: Is AND-operator short-circuiting in Pascal?
Du kannst für den Teil auch einfach den $B umschalten:m.fuchs hat geschrieben: Mi 16. Nov 2022, 11:56Nicht zwangsläufig. Tatsächlich bin ich bisher noch nicht darüber gestolpert. Für die Zukunft weiß ich jetzt aber: wenn ich zwei Funktionen ausführen und deren Rückgabewerte per and verknüpfen möchte, dann muss ich Hilfsvariablen benutzen. Kommt sicher selten vor, aber kann auch vorkommen.Winni hat geschrieben: Mi 16. Nov 2022, 10:43Wer halbwegs sauberen Code schreibt, ist mit boolean short-circuit auf der völlig sicheren Seite.
Code: Alles auswählen
{$push}{$B-}
if funcA() and funcB() then
...
{$pop}
Ist Short-Circuiting aktiv, so ändert der Compiler die Reihenfolge nicht. Ist es nicht aktiv, macht der Compiler da in der Tat Optimierungen, wenn es sich anbietet.m.fuchs hat geschrieben: Mi 16. Nov 2022, 11:56 Unter anderem damit der Compiler eventuell auch die Reihenfolge der Aussagen verändern kann. Hmmmm.
Wir werden wahrscheinlich irgendwann mal Unterstützung für and_then und or_then aus ISO Extended Pascal einbauen. Womöglich aber auch nur in diesem Modus oder mit einem entsprechenden Modusschalter.m.fuchs hat geschrieben: Mi 16. Nov 2022, 10:13 Wie dem auch sei: aus meiner Sicht wäre eine Unterscheidung der Optimierung durch unterschiedliche Operatoren wie and und andalso oder so etwas die bessere Wahl.
Die kann man in seinem Code je nach Notwendigkeit einsetzen.
FPC Compiler Entwickler
- af0815
- Lazarusforum e. V.
- Beiträge: 6776
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Is AND-operator short-circuiting in Pascal?
Das wäre eine Information die in die Referenz https://www.freepascal.org/docs-html/cu ... ogsu4.html IMHO hineingehören würde. Weil damit ist es klar und definiert, wie der Compiler sich verhält.PascalDragon hat geschrieben: Do 17. Nov 2022, 07:51 Ist Short-Circuiting aktiv, so ändert der Compiler die Reihenfolge nicht. Ist es nicht aktiv, macht der Compiler da in der Tat Optimierungen, wenn es sich anbietet.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1645
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: Is AND-operator short-circuiting in Pascal?
Mein erster Kontakt zu $b- war mit Borland Pascal 5. Da stand explizit in der Anleitung für Turbo Vision Programme, daß diese mit B- übersetzt werden müssen.
if (Objekt <> nil) and (Objekt^.Whatever) then ...
wäre sonst in die Hose gegangen.
if (Objekt <> nil) and (Objekt^.Whatever) then ...
wäre sonst in die Hose gegangen.
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Is AND-operator short-circuiting in Pascal?
Hi!
{$B-} gab es ab Turbo 4.0 als Boolean short-circuit
In den Versionen 1.0 bis 3.0 wurde mit {$B ...} der Standard Input/Output gewählt: Terminal (TRM) oder Konsole (CON).
Wie praktisch {$B-} ist, sei nur an einem kurzen Beispiel gezeigt:
Im Modus {$B+} müsste man das in 2 Bedingungen schachteln, weil es sonst bei s[1] krachen könnte.
Winni
{$B-} gab es ab Turbo 4.0 als Boolean short-circuit
In den Versionen 1.0 bis 3.0 wurde mit {$B ...} der Standard Input/Output gewählt: Terminal (TRM) oder Konsole (CON).
Wie praktisch {$B-} ist, sei nur an einem kurzen Beispiel gezeigt:
Code: Alles auswählen
procedure StripLeadingBlanks (var s : string);
begin
While (length(s) > 0) and (s[1] = #32) do delete (s,1,1);
end;
Winni
- kupferstecher
- Beiträge: 431
- Registriert: Do 17. Nov 2016, 11:52
Re: Is AND-operator short-circuiting in Pascal?
Die Reihenfolge zu optimieren denke ich bringt in der Praxis wenig Performancegewinn. Außer der Compiler könnte dann gleichzeitig die Auswertung vorzeitig abbrechen, aber beide Optimierungen schließen sich ja gegenseitig aus.m.fuchs hat geschrieben: Mi 16. Nov 2022, 11:56 Ach halt, es liegt gar nicht an Pascal. N. Wirth hatte Short-Circuit nicht vorgesehen. Unter anderem damit der Compiler eventuell auch die Reihenfolge der Aussagen verändern kann.
Ich finde es nett, dass der Compiler bei einer Zeile wie
If (key=vk_o) and (ssCtrl in Shift) then ...
unaufgefordert Short-Circuiting betreibt, auch wenn die paar Takte in diesem Beispiel kaum der Rede wert sind.
Mit andthen könnte ich auch leben, ist halt wieder das Problem der Rückwärts(in)kompatibilität. Mit and_then weniger, das macht das ganze Schriftbild kaputt

In Pascal ist das Short-Circuiting m.E. weniger dramatisch, weil man gemäß der Pascal-Philosophie sowieso nicht größere Funktionalitäten in if-Bedingungen verstecken sollte.
-
- Lazarusforum e. V.
- Beiträge: 395
- Registriert: Sa 15. Mai 2010, 13:46
- CPU-Target: 64 bit
- Kontaktdaten:
Re: Is AND-operator short-circuiting in Pascal?
Da aktuell ja das normale and standardgemäß genau das tut, fände ich m.fuchs Vorschlag besser, das so zu lassen und den no-short-circuiting-Fall mit andAlso sowie orAlso anzubieten, statt mit {$push}{$B-}[...]{$pop}.Wir werden wahrscheinlich irgendwann mal Unterstützung für and_then und or_then aus ISO Extended Pascal einbauen.
So Sachen, wie
Code: Alles auswählen
if (obj <> nil) and (obj.ready) then ...
if (length(arr) > 0) and (arr[0] = x) then ...
- af0815
- Lazarusforum e. V.
- Beiträge: 6776
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Is AND-operator short-circuiting in Pascal?
Und wozu brauche ich dann B+ ? Denn dort dürfen Parameter umsortiert/optimiert werden. B- ist ja ein Sonderfall einer effizienten OptimierungMitjaStachowiak hat geschrieben: Do 17. Nov 2022, 13:42 So Sachen, wiesind schon so geläufig, dass man das Verhalten des regulären and nicht mehr ändern kann.Code: Alles auswählen
if (obj <> nil) and (obj.ready) then ... if (length(arr) > 0) and (arr[0] = x) then ...

Ich sehe keinen Sinn in andAlso bzw. orAlso. Bisher sind die mir wirklich nicht abgegangen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Lazarusforum e. V.
- Beiträge: 395
- Registriert: Sa 15. Mai 2010, 13:46
- CPU-Target: 64 bit
- Kontaktdaten:
Re: Is AND-operator short-circuiting in Pascal?
Der Punkt ist: Die Operatoren and und or haben mit {B+} und {B-} verschiedene, semantische Bedeutungen. Das ist nicht gut. Vor allem, weil man dieses Flag ja beliebig weit weg vom eigentlichen Ausdruck platzieren kann, sodass Pascal-Code plötzlich nicht mehr eindeutig ist.
Wenn jemand eine Unit, die jemand anderes angefangen hat, weiter entwickeln soll und da ggf. so ein Flag irgendwo gesetzt wird, dann führen Code-Schnipsel, die man gewohnheitsgemäß und überall sonst sicher verwenden kann, plötzlich zu instabilem Verhalten.
So eine <> nil-Prüfung baut man ja oft irgendwo als Sicherheit ein, obwohl dieser Fall normaler Weise nicht eintritt. Da das so banal und Standard ist, wird vielleicht auch kein Test-Case dafür angelegt. Und dann hat man instabile Software, obwohl man vielleicht nach allen Regeln der Kunst solide entwickelt hat...
Daher am besten eine non-short-circuiting-Version dieser Operatoren anbieten und das B-Flag deprecaden. Wenn man schon dabei ist:
Wie wäre es bei Methoden, Funktionen oder Properties mit einer Art unaltering-Direktive?
Ich bin nach etwas Nachdenken zu dem Schluss gekommen, dass FPC bei mehrfachen Peroperty-Zugriffen in einem Ausdruck nicht erkennen kann, ob man die durch Optimierungen zusammenfassen kann. Es kann ja z.B. sein, das ein Property eine Art Caching durchführt, sodass im Getter schon ein Schreibzugriff passiert. Nur dass es hier trotzdem egal ist, wie oft das property abgefragt wird. Der Compiler könnte den Zugriff also in einem Register puffern...
Wenn jemand eine Unit, die jemand anderes angefangen hat, weiter entwickeln soll und da ggf. so ein Flag irgendwo gesetzt wird, dann führen Code-Schnipsel, die man gewohnheitsgemäß und überall sonst sicher verwenden kann, plötzlich zu instabilem Verhalten.
So eine <> nil-Prüfung baut man ja oft irgendwo als Sicherheit ein, obwohl dieser Fall normaler Weise nicht eintritt. Da das so banal und Standard ist, wird vielleicht auch kein Test-Case dafür angelegt. Und dann hat man instabile Software, obwohl man vielleicht nach allen Regeln der Kunst solide entwickelt hat...
Daher am besten eine non-short-circuiting-Version dieser Operatoren anbieten und das B-Flag deprecaden. Wenn man schon dabei ist:
Wie wäre es bei Methoden, Funktionen oder Properties mit einer Art unaltering-Direktive?
Ich bin nach etwas Nachdenken zu dem Schluss gekommen, dass FPC bei mehrfachen Peroperty-Zugriffen in einem Ausdruck nicht erkennen kann, ob man die durch Optimierungen zusammenfassen kann. Es kann ja z.B. sein, das ein Property eine Art Caching durchführt, sodass im Getter schon ein Schreibzugriff passiert. Nur dass es hier trotzdem egal ist, wie oft das property abgefragt wird. Der Compiler könnte den Zugriff also in einem Register puffern...
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1645
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: Is AND-operator short-circuiting in Pascal?
In dem Vergleich nach and könnte eine Funktion aufgerufen werden, die globale Variablen ändert. Bei B+ wird die sicher aufgerufen bei B- nur dann, wenn der Ausdruck vor dem and true ergibt.af0815 hat geschrieben: Do 17. Nov 2022, 14:35 ...
Und wozu brauche ich dann B+ ? Denn dort dürfen Parameter umsortiert/optimiert werden. B- ist ja ein Sonderfall einer effizienten Optimierung
Ich sehe keinen Sinn in andAlso bzw. orAlso. Bisher sind die mir wirklich nicht abgegangen.
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Is AND-operator short-circuiting in Pascal?
Hi!fliegermichl hat geschrieben: Do 17. Nov 2022, 14:58
In dem Vergleich nach and könnte eine Funktion aufgerufen werden, die globale Variablen ändert. Bei B+ wird die sicher aufgerufen bei B- nur dann, wenn der Ausdruck vor dem and true ergibt.
Das hat dann aber nichts mehr mit sauberer Programmierung zu tun, wenn die Funktionen wilde Seiteneffekte haben.
Mir ist in der Tat kein Fall bekannt, bei dem man {$B+} sinnvoll einetzen könnte.
Winni
- af0815
- Lazarusforum e. V.
- Beiträge: 6776
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Is AND-operator short-circuiting in Pascal?
Ok, das leuchtet ein. Ein super Fall für defensive Programmierung. Sorry aber mein Verständnis ist dafür sehr begrenzt, zumindest bis ich in Pension gehe.fliegermichl hat geschrieben: Do 17. Nov 2022, 14:58In dem Vergleich nach and könnte eine Funktion aufgerufen werden, die globale Variablen ändert. Bei B+ wird die sicher aufgerufen bei B- nur dann, wenn der Ausdruck vor dem and true ergibt.af0815 hat geschrieben: Do 17. Nov 2022, 14:35 ...
Und wozu brauche ich dann B+ ? Denn dort dürfen Parameter umsortiert/optimiert werden. B- ist ja ein Sonderfall einer effizienten Optimierung
Ich sehe keinen Sinn in andAlso bzw. orAlso. Bisher sind die mir wirklich nicht abgegangen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Lazarusforum e. V.
- Beiträge: 395
- Registriert: Sa 15. Mai 2010, 13:46
- CPU-Target: 64 bit
- Kontaktdaten:
Re: Is AND-operator short-circuiting in Pascal?
Ich hatte in einem Javascriptprogramm mal irgendwann den Fall, ein and ohne short-circuiting zu brauchen. Aber ja, es ist schon selten. Deswegen darf das sich auch gerne hinter einem langen Schlüsselwort verstecken...