True or False or False = False!

True or False or False = False!

(True or False or False) = True.

function TPSDConnectionMonitor.IsOnline: Boolean;

var

  cState: TPSDConnectionState;

begin

  Result := (Not OfflineStoreEnabled) or (Not Enabled) or IsOnline(cState);

end;

See the picture.  

FOfflineStoreEnabled = False

FEnabled = True

IsOnline(cState) does an and between two states and returns False

The expression

 (Not OfflineStoreEnabled) or (Not Enabled) or IsOnline(cState)

is (True) or (False) or False

and Result is False! #WTF  

Add extra paranthesis to the expression 

( (Not OfflineStoreEnabled) or (Not Enabled) or IsOnline(cState))

is ((True) or (False) or False)

and Result is True as expected!

Can someone make sense of this?

#XE5  

14 thoughts on “True or False or False = False!


  1. Doh! It was some sort of Heisenbug after all.  


    A removal of parenthesis and clean and build does not replicate the issue.


    This is not the first time I’ve seen it, though – but it was the first time I recorded a screenshot.

    Like


  2. As far as I remember this kind of compilation tricks are the result of the shortcut boolean evaluation, without the use of explicit parenthesis it wil become an error/bug. You have two options, complete boolean evaluation or explicit parenthesis, I recomend the second one, never fails (at least to my personal experience).

    Like


  3. Totally agree with Heinz Toskano here, I always put an enclosing set of parentheses on a compound logic evaluation like that. There are always issues with the boolean logic not quite working otherwise, I’m sure I remember a white paper about it, can’t remember the why or wherefore of it though.


    AFAIK it’s to do with the compiler settings around boolean evaluation, but I can’t honestly remember.

    Like


  4. Heinz Toskano – Short circuit Boolean evaluation will stop execution


    – at first False for and statements


    – at first True for or statement


    Docs state: “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.”


    Parenthesis should not affect the evaluation as sub expressions also have the  short circuit eval applied , although I do agree that explicit use of parenthesis is a good thing for readability many times.


    In my example above, the first (not false) should still have returned true.

    Like


  5. function TPSDConnectionMonitor.IsOnline : Boolean;


    var


      cState: TPSDConnectionState;


    begin


      try


         Result := (Not OfflineStoreEnabled) or (Not Enabled) or IsOnline(cState);


      exception


         on E : Exception do


              Showmessage(E.Message);


      end;


    end;


    ??? 🙂 Exception in IsOnline method ???

    Like


  6. Dobrin Petkov – cState is an out argument, and that version of IsOnline is exception safe, dealing only with copied values, not pointers or objects. Besides evaluation is LEFT to right, and no exception is raised.  OfflineStoreEnabled is the first, and if (not OfflineStoreEnabled) is true, that should be the result.

    Like


  7. Vladimir Srednikh – Unfortunately, the bug disappeared after a build. I did repeatedly see it happen before the rebuild, but I am unable to reproduce it. Next time, I’ll make sure that I capture the assembly code as well.

    Like

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.