Recent

Author Topic: Boolean type  (Read 7410 times)

LemonParty

  • Full Member
  • ***
  • Posts: 185
Boolean type
« on: April 13, 2025, 07:04:14 pm »
Hello.

I am interesting if Boolean type represented as $1(for True) on all platforms or it may be platforms where True value may be some nonzero value like $FF.
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

jamie

  • Hero Member
  • *****
  • Posts: 6964
Re: Boolean type
« Reply #1 on: April 13, 2025, 07:58:10 pm »
True is always any value other than 0

Many APIs in windows use a return value as both a value to indicate something and also as a true or false at the same time.

Code: Pascal  [Select][+][-]
  1.  If lastValue then do_something with LastValue;
  2.  

 There if  LastValue isn't 0 then it's true but as you can see it also is used for value returns, too.

 Finding the value of 1 in code for a true is most of the time just a convenience to make the toggling logic easier for the compiler to make code more efficient code in complex bool code, it really has no designation.


Jamie
The only true wisdom is knowing you know nothing

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11361
  • Debugger - SynEdit - and more
    • wiki
Re: Boolean type
« Reply #2 on: April 13, 2025, 08:52:16 pm »
True is always any value other than 0

NO !

Or, well it depends what we are talking about.

"Boolean" as defined by Pascal is an enumeration. The ordinal value of False and True are 0 and 1.

Casting any other value to boolean (e.g.  Boolean(9) ) is not allowed, and results in undefined behaviour. It may sometimes behave as True and sometime as False. (If you try it, and don't get that, then you did not try hard enough)


In "boolean" expressions numbers don't have a "boolean" value.   If 1 then ...; does not work.

But FPC has several boolean types.

There are Bytebool, WordBool, ... and they can cast/store any int value (within their range) and for them 0 is false, all else is true.
https://www.freepascal.org/docs-html/current/ref/refsu4.html

jamie

  • Hero Member
  • *****
  • Posts: 6964
Re: Boolean type
« Reply #3 on: April 13, 2025, 09:03:18 pm »
I have to disagree with you the has has allways been that way zero is always false anything else is always true no matter what language you deal with and that's the one argument that I'm not going to back down on.

 In math its the same way.

Various values for true can be used for true except for 0.
Compiler logic uses the 1 as a more code efficient way to deal with complex bool operations.

 When directly assigning a 1 value has really nothlng to do with the language, it just makes it more code sence.
  You can pass any value as a bool to a function for true and it will accept it because onlu 0 is the important value in all language and math fir false.

 Have a good day, this is the last ill address this.
Jamie
« Last Edit: April 13, 2025, 09:05:05 pm by jamie »
The only true wisdom is knowing you know nothing

440bx

  • Hero Member
  • *****
  • Posts: 5477
Re: Boolean type
« Reply #4 on: April 13, 2025, 09:30:04 pm »
The documentation about the "boolean' types say one thing but, the behavior is a different thing.

In theory, only the BOOL types will consider any non zero value to be true while, the "boolean" types (e.g, Boolean16) will only consider a value of 1 to be true.  The reality is, as far as truth value the "boolean" types behave exactly the same way as the BOOL types.

That said, the compiler generates code that is inconsistent with the rules stated in the documentation.  For instance, it tests AX to determine if a _boolean_ is true or false.  That's incorrect, that's only valid for "BOOL" types.  For "boolean" types, the correct test is ANDing with 1.

Suggestion: treat the "boolean" types as being _functionally_ the same as the "BOOL" types. 
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11361
  • Debugger - SynEdit - and more
    • wiki
Re: Boolean type
« Reply #5 on: April 13, 2025, 09:42:22 pm »
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. var
  4.   a, b: Integer;
  5. begin
  6.   a := 1;
  7.   b := 2 + random(5); // prevent constant eval
  8.  
  9.   if (b>a) = Boolean(b) then
  10.     write('yes')
  11.   else
  12.     write('no');
  13.   readln;
  14. end.
  15.  

Prints "no" for me.

"b" is between 2 and 7 (so not zero). According to your statement, then that would be true.

b is also greater than a.

So the "if" has "True = True". Yet it goes into the "else" branch.



Mind that results may vary (random), depending on compiler version, compiler settings (optimization), even target arch, ....

440bx

  • Hero Member
  • *****
  • Posts: 5477
Re: Boolean type
« Reply #6 on: April 13, 2025, 10:04:05 pm »
That almost sounds good but, there is a problem with it... here is your code with a couple of lines added to it:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. var
  4.   a, b: Integer;
  5. begin
  6.   a := 1;
  7.   b := 2 + random(5); // prevent constant eval
  8.  
  9.   if (b>a) = Boolean(b) then
  10.     write('yes')
  11.   else
  12.     write('no');
  13.  
  14.  
  15.   if boolean(b) then
  16.     write('yes')
  17.   else
  18.     write('no');
  19.  
  20.   readln;
  21. end.
  22.  
Lo and behold, boolean(b) is TRUE.  What your original code proves is that there are cases in FPC where two expressions that evaluate to TRUE are NOT _logically_ equal (even though they are both TRUE).  IOW, there are cases in FPC where TRUE <> TRUE (and according to some, somehow that's not a bug... it's just "undefined behavior"... there are some occasions where FPC takes "undefined behavior" to new heights.)

The code generated by the compiler is WRONG and that is the reason the first test yields false.  The code generated by the compiler to test for boolean(b) is also wrong, it uses "test al, al" therefore any non zero value in al will yield true which is incorrect since it violates the definition of boolean, both the mathematical one and the documented one.

This whole thing was already discussed ad nauseam in the thread
https://forum.lazarus.freepascal.org/index.php/topic,70004.0.html
and that thread made it very obvious that those FPC bugs are here to stay.  Logical and mathematical correctness isn't something that is going to get in FPC's way.

Wanna be safe ? ... consider any "boolean" type as behaving the same as BOOL.  There is NO true boolean type in FPC (and likely Delphi... but, since I don't use it, I don't care.)

Getting a true boolean type in FPC is programmer's responsibility.  The compiler will not help enforce the characteristics of a genuine/true boolean type.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11361
  • Debugger - SynEdit - and more
    • wiki
Re: Boolean type
« Reply #7 on: April 13, 2025, 10:35:07 pm »
Lo and behold, boolean(b) is TRUE.  What your original code proves is that there are cases in FPC where two expressions that evaluate to TRUE are NOT _logically_ equal (even though they are both TRUE).  IOW, there are cases in FPC where TRUE <> TRUE (and according to some, somehow that's not a bug... it's just "undefined behavior"...

You are right, it's undefined behaviour. But you are wrong. "boolean(b)" is not true, nor is it false. It is undefined. Hence the behaviour is undefined too.

Of course if you look at this from a low level machine code point of view, and if you apply none-Pascal or generalized meanings of True/False, then the statement might be more than what you said.

But since this is about Pascal, and probably specifically fpc style, applying other conventions seems a bit out of scope?

440bx

  • Hero Member
  • *****
  • Posts: 5477
Re: Boolean type
« Reply #8 on: April 13, 2025, 10:53:51 pm »
But since this is about Pascal, and probably specifically fpc style, applying other conventions seems a bit out of scope?
It's about what is logically and mathematically correct.

FPC's documentation states that when it comes to the boolean type only the value 1 is considered TRUE but, that is not true.  FPC considers values other than 1 to be TRUE and that can be seen in the code it generates.  For a boolean type it is _incorrect_ to generate a test al, al to determine the truth value of the boolean type.  The _correct_ instruction is to and the register with 1.

No matter how anyone wishes to slice it.  FPC does _not_ handle booleans as it states in the documentation that it does and, generates code that is invalid to manage a boolean type.  It generates code for the C BOOL type, that's what it does in all cases, that's why it uses test al, al (which is incorrect for boolean types.)

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11361
  • Debugger - SynEdit - and more
    • wiki
Re: Boolean type
« Reply #9 on: April 13, 2025, 11:15:34 pm »
But since this is about Pascal, and probably specifically fpc style, applying other conventions seems a bit out of scope?
It's about what is logically and mathematically correct.
Speaking about a numerical value for "true", are you sure that in maths (i.e. boolean algebra) there is a numerical value to the logical states?

I could have sworn that is a by product of information technology.... (And this topic started about numerical values...).

Quote
FPC's documentation states that when it comes to the boolean type only the value 1 is considered TRUE but, that is not true.  FPC considers values other than 1 to be TRUE

Does it, or does it consider them undefined?

Because the result can by chance be identical. An undefined value is allowed to behave like "true", that does not break the contract.

I know, you refer to the machine code, that does not explicitly perform the check for "1". But it performs a check that will always based on the following ordinary values of a bool behave for
- 0 as false
- 1 as true
- other as either (where "either" can is some case be a fixed choice, but is not guaranteed to be fixed)

Also:
I am neither going to reread the linked thread for any word picking in it, nor analyse the documentation for any potential English wording that could be twisted to more than one meaning.

It may be or not be that the documentation could be improved.
But, I can (I have the ability, and the good will) read it as (with regards to boolean / ignore bytebool)
0 is the ordinary value of false
1 is the ord val of true
any other ord value is not defined, and considered undefined.

And example asm code like testing "tst rax" or "or rax, rax" followed by only on of "be" or "bz" => is totally in line with that. It does not break the undefined state.

440bx

  • Hero Member
  • *****
  • Posts: 5477
Re: Boolean type
« Reply #10 on: April 14, 2025, 01:16:06 am »
Speaking about a numerical value for "true", are you sure that in maths (i.e. boolean algebra) there is a numerical value to the logical states?
boolean is two states.  Those can be ON and OFF or in a gate, low voltage and high voltage, if you assign a numeric value to those states then you get 0 and 1.  It's been convention, for centuries I believe, to assign zero to false and 1 to true (unless I'm mistaken George Boole is responsible for that one.)

I could have sworn that is a by product of information technology.... (And this topic started about numerical values...).
Again, unless I am mistaken Boole started that thing.

Does it, or does it consider them undefined?
The documentation is crystal clear.  for all boolean types (not BOOL types) 1 is TRUE and 0 is FALSE.  It's right there in black and white.  That's what the documentation states, that's very far from what FPC enforces and considers as TRUE which for FPC is any value other than zero.

The problem is that FPC generates code that does NOT enforce the documented rule for boolean types (0 = FALSE, 1 and only 1 = TRUE).   There is no true boolean type in FPC.  There is only a BOOL type easily demonstrated by the code it generates: it does NOT generate code to test that the value of a boolean is 1, it generates code to test that the value is non-zero.  Consequence: there are only BOOL types in FPC.

The truly sad part is that, that bug cannot easily be corrected without breaking existing code.  There is plenty of code out there that depends on boolean being true for values that are simply non-zero.  The only way not to break that code is to make the correct behavior be depending on a new mode (e.g, USETRUEBOOLEAN) which, it doesn't look like the FPC developers are willing to entertain.

But, maybe FPC should consider assigning 42 to TRUE and 32 to FALSE.  Why would anyone be "stuck" on 0 and 1 ??? no reason for that ;)


(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 17196
  • Ceterum censeo Trump esse delendam
Re: Boolean type
« Reply #11 on: April 14, 2025, 07:38:00 am »
So:
Code: Pascal  [Select][+][-]
  1. type
  2.   MyBool = (nothing,something);
The problem being that many compilers define false/true as 0/1, but then they start optimizing this strictness away, like fairly recent C++ and all llvm based compilers.
At least fpc tries to prevent this "optimization" where true is not false
« Last Edit: April 14, 2025, 08:46:59 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Khrys

  • Full Member
  • ***
  • Posts: 243
Re: Boolean type
« Reply #12 on: April 14, 2025, 07:43:54 am »
Like @440bx said, this topic has already been discussed to death.

No matter whether you believe the documentation to be wrong or the programmer using non-1 integers for  True  to be at fault,
saying that  Integer(ABool)  will always be 1 is simply bad advice that shouldn't be relied upon in practice.

Code like this (which I've been tempted to write before!) is just waiting to blow up in your face, especially when e.g. you innocently try passing it  Boolean(Res)  where  Res  is the  bool  return value of an external C function:

Code: Pascal  [Select][+][-]
  1. function CountTrue(A, B, C, D: Boolean): Integer;
  2. begin
  3.   Result := Integer(A) + Integer(B) + Integer(C) + Integer(D); // May return any integer up to 1020
  4. end;

Thaddy

  • Hero Member
  • *****
  • Posts: 17196
  • Ceterum censeo Trump esse delendam
Re: Boolean type
« Reply #13 on: April 14, 2025, 08:49:33 am »
I believe I gave a similar example in a previous discussion and also filed a bug report.
Especially with interfacing in other languages it can blow up indeed, but not only that: e.g. llvm based compilers only blow up with at least -O3.
I demonstrated that with a simple C lib that assumed the docs were correct for the compiler, i.e 0 and 1. Blew up when optimized.
Must be somewhere here on the forum.
« Last Edit: April 14, 2025, 08:51:51 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11361
  • Debugger - SynEdit - and more
    • wiki
Re: Boolean type
« Reply #14 on: April 14, 2025, 10:29:43 am »
Speaking about a numerical value for "true", are you sure that in maths (i.e. boolean algebra) there is a numerical value to the logical states?
boolean is two states.  Those can be ON and OFF or in a gate, low voltage and high voltage, if you assign a numeric value to those states then you get 0 and 1.  It's been convention, for centuries I believe, to assign zero to false and 1 to true (unless I'm mistaken George Boole is responsible for that one.)

Ok, I didn't know. But even if, as you said its 2 tokens.

For all else, they are 2 tokens for  - as you wrote - 2 states.

Unfortunately you simple ignored about half of the previous statement.

If the token is not readable (never mind why that can happen, or if the choices that allow it to happen aren't choices that make you happy), then something must happen. It could be a crash, an exception, or an undefined behaviour. The latter was chosen. Maybe not your preferred choice, none the less a valid one.

You keep doing a mix of ignoring and misrepresenting it. Your choice. Valid choice as well, but not a choice on which I will waste my time.

 

TinyPortal © 2005-2018