Recent

Author Topic: Boolean type  (Read 7431 times)

simone

  • Hero Member
  • *****
  • Posts: 666
Re: Boolean type
« Reply #60 on: April 21, 2025, 09:15:37 pm »
Why doesn't the compiler emit an invalid cast message error?

Edit: The error is clearly intentional.
« Last Edit: April 21, 2025, 09:18:35 pm by simone »
Microsoft Windows 10/11 64 bit - Lazarus 3.8/4.0 FPC 3.2.2 x86_64-win64-win32/win64

dseligo

  • Hero Member
  • *****
  • Posts: 1522
Re: Boolean type
« Reply #61 on: April 21, 2025, 09:39:06 pm »
Why doesn't the compiler emit an invalid cast message error?

Edit: The error is clearly intentional.

I don't see need for it.

As it says here https://wiki.freepascal.org/Typecast: Typecasting is the concept, allowing to assign values of variables or expressions, that do not match the variable’s data type, virtually overriding Pascal’s strong typing system.

So, you are overriding Pascal’s strong typing system: you are on your own.

It says here https://www.freepascal.org/docs-html/ref/refse85.html: It is a bad idea to typecast integer types to real types and vice versa.
If you want to, you can make bug report against documentation to say that is also bad idea to typecast integer types to boolean. :)

Paolo

  • Hero Member
  • *****
  • Posts: 584
Re: Boolean type
« Reply #62 on: April 21, 2025, 10:06:46 pm »
Quote
I don't see need for it.
+1.

If you force the type, the result is your responsability.

LV

  • Sr. Member
  • ****
  • Posts: 295
Re: Boolean type
« Reply #63 on: April 21, 2025, 10:10:18 pm »
Why doesn't the compiler emit an invalid cast message error?

Edit: The error is clearly intentional.

The compiler has nothing to do with it. This is a common issue in mathematical logic regarding normalization.

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$mode ObjFpc}
  3.  
  4. var
  5.   B1, B2: boolean;
  6.  
  7. begin
  8.   B1 := boolean(1); // True (stored as 1)
  9.   B2 := boolean(2); // True (stored as 2)
  10.  
  11.   writeln(B1);        // Output: TRUE
  12.   writeln(B2);        // Output: TRUE
  13.   writeln(B1 and B2); // Output: TRUE
  14.  
  15.   // Compare by normalizing to 0/1
  16.   writeln( (integer(B1) <> 0) = (integer(B2) <> 0) ); // Output: TRUE
  17.  
  18.   readln;
  19. end.  
  20.  

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12269
  • FPC developer.
Re: Boolean type
« Reply #64 on: April 21, 2025, 10:18:20 pm »

Code: [Select]
  writeln(B1);        // Output: TRUE    CORRECT
  writeln(B2);        // Output: TRUE    IMPLEMENTATION DEFINED
  writeln(B1 and B2); // Output: TRUE IMPLEMENTATION DEFINED
 
  // Compare by normalizing to 0/1
  writeln( (integer(B1) <> 0) = (integer(B2) <> 0) ); // Output: TRUE   CORRECT, but because the typecasts force BOOL, not BOOLEAN semantics

The IMPLEMENTATION DEFINED results are not guaranteed.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11361
  • Debugger - SynEdit - and more
    • wiki
Re: Boolean type
« Reply #65 on: April 21, 2025, 10:24:16 pm »
Code: Pascal  [Select][+][-]
  1.   // Compare by normalizing to 0/1
  2.   writeln( (integer(B1) <> 0) = (integer(B2) <> 0) ); // Output: TRUE
  3.  

That example is truly bad. It might be (part of) why 440bx is so strongly against the ability to use typecasts on boolean. (Albeit, his arguments are still wrong, as they simple aren't true).

If you wanted to use it as boolean, you shouldn't have type casted, but done
Code: Pascal  [Select][+][-]
  1.  B2 := 2 <> 0; // or whatever in the definition of your data defines that 2 should be converted to true.



Type cast you use, if you don't want it to be treated as boolean. (because you give up that option)

Let's say you use some code that has a public field
Code: Pascal  [Select][+][-]
  1. property FooBar: boolean;
You don't need FooBar, but you need storage for something else. And you can't extend the class/record/object.

Then you could (like it is often done with "Tag") store your date (e.g. an integer) in that property
Code: Pascal  [Select][+][-]
  1. MyObj.FooBar := Boolean(MyInt);
And later
Code: Pascal  [Select][+][-]
  1. MyInt := Integer(MyObj.FooBar);

And if you do that, you use it as storage only. While doing so, you would have no reason to treat it as boolean.




Of course there are cases where you typecast and will use it as boolean afterwards.

That is if you have previously done
Code: Pascal  [Select][+][-]
  1. MyObj.Tag := integer(MyValidBool);  // Tag is integer
Then you know Tag must have data that can be cast back to a boolean, and have a value valid for boolean usage. So then you can cast that back later, and use it.

Of course your responsibility that Tag does not get changed in between.

simone

  • Hero Member
  • *****
  • Posts: 666
Re: Boolean type
« Reply #66 on: April 21, 2025, 10:36:48 pm »
The purpose of my example, intentionally incorrect and extreme, was to show a concrete paradox that arises from what was clearly explained in previous posts about boolean type implementation of fpc.

In a language with static and strong typing like Object Pascal, silent errors like True=True is False should not happen, in my humble opinion.
Microsoft Windows 10/11 64 bit - Lazarus 3.8/4.0 FPC 3.2.2 x86_64-win64-win32/win64

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11361
  • Debugger - SynEdit - and more
    • wiki
Re: Boolean type
« Reply #67 on: April 21, 2025, 10:42:47 pm »
The purpose of my example, intentionally incorrect and extreme, was to show a concrete paradox that arises from what was clearly explained in previous posts about boolean type implementation of fpc.

In a language with static and strong typing like Object Pascal, silent errors like True=True is False should not happen, in my humble opinion.

But then you would also have to say, that
Code: Pascal  [Select][+][-]
  1. writeln(TStringList(1).Count);
must return some sensible number.

It is clearly typed as a TStringList.

The fact is, that Pascal has a part that is strongly typed.

And Pascal has a part that is not, and that allows to break out of that type-system. Warts and all.

simone

  • Hero Member
  • *****
  • Posts: 666
Re: Boolean type
« Reply #68 on: April 21, 2025, 10:57:16 pm »
The fact is, that Pascal has a part that is strongly typed.

And Pascal has a part that is not, and that allows to break out of that type-system. Warts and all.

I had guessed that in the past, but thank you for stating it clearly.

The problem, sometimes, is to figure out where the underlying type system is strong or weak.
« Last Edit: April 21, 2025, 10:59:43 pm by simone »
Microsoft Windows 10/11 64 bit - Lazarus 3.8/4.0 FPC 3.2.2 x86_64-win64-win32/win64

Zoran

  • Hero Member
  • *****
  • Posts: 1949
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Boolean type
« Reply #69 on: April 21, 2025, 11:17:40 pm »
The container which can be a byte, a word, a dword or a qword, is totally irrelevant.  The only thing that matters is a single bit, one the compiler chose to represent the boolean value.

No. Having one bit to represent two states and disregard other bits would have been a valid way to represent boolean, had it be chosen. There are other valid ways to store boolean too.
As documented, the chosen way is that the size is one byte (I hope you don't oppose the one byte choice for size, do you?) and that zero in all bits represent false value and 1 in bit 0, together with zeros in all other bits represents true value. All other 254 possible values of the boolean value, that is all values which have any bit other than bit 0 set, are undefined. This choice is perfectly valid.

And when this choice was made, it was so that the relation False < True equals True.
This relation is documented, so it must not be violated, keep that in mind when suggesting to treat any byte with bit 0 set to 1 as True.

FPC does NOT implement booleans, it implements C's BOOL.  When it comes to the boolean type, it only works as long as it is considered a BOOL and NOT a boolean.
No. In fpc Boolean is what fpc documentation says, nothing else. And what you mean by "booleans" there remains unclear.
 - in C, any non-zero value means True. It is not so with Boolean in fpc. Although you might experience the behaviour which appear so, it is not documented and, unlike in C, you must not rely on it.
 - in FPC valid Boolean values are comparable - false < true - you can rely on it. Not so in C.
The types from other languages have nothing to do with how Boolean is defined in FPC. There are types in FPC which are documented to behave like C, but not Boolean.

That's the reason why when using booleans, FPC can end up in situations where TRUE <> TRUE

This situation is not
Code: [Select]
True <> True, it is
Code: [Select]
oneVariableWithUndefinedValue  someRelationOperator  anotherVariableWithUndefinedValueYou can't expect a predictable value from this expression. You get something once, another time something else. Or even worse, you will get the same outcome always, and your user something else.

but, when the compiler does that atrocity, it's "undefined territory" (but, of course, it is!) just like when a drunk drives into a tree, it's the tree that got in the way (obviously!.)

That's how it works, you need to take care yourself to avoid the crash. But you are in control, and as long as you don't overuse alcohol when programming, the tree doesn't get in the way.
Swan, ZX Spectrum emulator https://github.com/zoran-vucenovic/swan

Zoran

  • Hero Member
  • *****
  • Posts: 1949
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Boolean type
« Reply #70 on: April 21, 2025, 11:47:32 pm »
The problem, sometimes, is to figure out where the underlying type system is strong or weak.

Pascal has "unsafe" constructs, but they aren't safe only if you don't really know what you are doing - see the five points (2-5) in my post above. These constructs are introduced to allow skipping the strong type system, so they weaken the type system, but they actually give the real strength to this language. The original Pascal, as created fifty years ago didn't have them, that's why it got the "toy language" reputation.
To get the real power, learn to use them well and don't hesitate to use them. When used well and carefully, they are safe.

As I said, you cannot get an undefined value in a boolean variable without using these unsafe constructs. In your examples you use explicit type cast. Fill free to use it whenever you need, but carefully - keep in mind that the type casting exists to allow skipping strong type system. That is what it is for.
Swan, ZX Spectrum emulator https://github.com/zoran-vucenovic/swan

simone

  • Hero Member
  • *****
  • Posts: 666
Re: Boolean type
« Reply #71 on: April 21, 2025, 11:59:56 pm »
However GnuPascal (1), an old and abandoned, but respectable implementation of Pascal, with my example, generates a compilation error ("constant out of range") when attempting to cast 2 to a boolean, in line #8.

So my expectation of an error message from the compiler is not so unreasonable.

(1): Tried using on line version available from ideone.com
« Last Edit: April 22, 2025, 12:19:09 am by simone »
Microsoft Windows 10/11 64 bit - Lazarus 3.8/4.0 FPC 3.2.2 x86_64-win64-win32/win64

Zoran

  • Hero Member
  • *****
  • Posts: 1949
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Boolean type
« Reply #72 on: April 22, 2025, 12:21:19 am »
However GnuPascal, an old and abandoned, but respectable implementation of Pascal, with my example, generates a compilation error ("constant out of range") when attempting to cast 2 to a boolean.

So my expectation of an error message from the compiler is not so unreasonable.

I have never tried GNU Pascal, so I don't know its rules, but I believe that, unlike FPC, it doesn't follow Borland's extensions, but the iso standard object pascal.
Look at the fpc object pascal (at least it is so with the most popular compiler modes) as a dialect of Borland line. This Borland line has its own rules, which fpc inherited from Delphi.

With type casting you are skipping the strong type system. That's it.
Swan, ZX Spectrum emulator https://github.com/zoran-vucenovic/swan

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Boolean type
« Reply #73 on: April 22, 2025, 01:14:28 am »
I have never tried GNU Pascal, so I don't know its rules, but I believe that, unlike FPC, it doesn't follow Borland's extensions, but the iso standard object pascal.
Indeed the latter, although ISO pascal also does not explicitly seem to state how it is actually stored in memory. The behaviour though is described for both: true and false are the only two options.

For gnu see https://www.gnu-pascal.org/gpc/Boolean.html
Today is tomorrow's yesterday.

Zoran

  • Hero Member
  • *****
  • Posts: 1949
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Boolean type
« Reply #74 on: April 22, 2025, 01:28:59 am »

Indeed the latter, although ISO pascal also does not explicitly seem to state how it is actually stored in memory.

It does, actually (another link in the page you gave): https://www.gnu-pascal.org/gpc/Boolean-_0028Intrinsic_0029.html#Boolean-_0028Intrinsic_0029
Swan, ZX Spectrum emulator https://github.com/zoran-vucenovic/swan

 

TinyPortal © 2005-2018