Recent

Author Topic: Boolean type  (Read 7674 times)

Thaddy

  • Hero Member
  • *****
  • Posts: 17423
  • Ceterum censeo Trumpum esse delendum (Tnx Charlie)
Re: Boolean type
« Reply #90 on: April 22, 2025, 03:38:08 pm »
The auto conversion is indeed a problem and hell when you want to use C style casts. The work-around is using pointer types to what you want to cast.

The best way to show that is trying to translate any and all examples in the famous "bit twiddling hacks" from stanford.
https://graphics.stanford.edu/~seander/bithacks.html
Some of which need adjusting in FPC because of implicit conversions.
This is known to the core compiler team.
I explained quite some decades ago:
“There are more things in heaven and earth, Horatio, than are dreamt of in your philosophy,” but fell on deaf ears. Eventually I used the pointer types to work around it. Although I understood Florian's and Jonas's reasoning regarding the Pascal language.

I used a practical application of this approach in the bit manipulation parts for the type helpers for integer types. That is: the parts I initially wrote.
« Last Edit: April 22, 2025, 03:52:13 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Khrys

  • Sr. Member
  • ****
  • Posts: 258
Re: Boolean type
« Reply #91 on: April 22, 2025, 03:52:52 pm »
Has there ever been a time where "cast" exclusively referred to bit pattern reinterpretation? (Genuine question)

In C, the standard way to convert between  int  and  double  is to use casts.
The C++ standard considers cast to be synonymous with explicit conversion. Furthermore,  std::bit_cast  isn't part of the core language; it's a standard library function.

(And by the way, "to cast" originally meant pouring molten metal into a mould, which also changes the metal's shape.)

440bx

  • Hero Member
  • *****
  • Posts: 5586
Re: Boolean type
« Reply #92 on: April 22, 2025, 03:57:24 pm »
using "absolute" is different than type casting.

"absolute" is used to declare a variable at a specific address.  This allows to place multiple variables of any type at the same address.  That's not typecasting, that's simply variable declaration at a specific address.

The purpose of typecasting is to re-interpret the meaning of some data (without having to declare a variable of some type at some address.)  For instance, the typecast "SomeDword := DWORD('abcd');"  changes the interpretation of 'abcd' from characters to their equivalent bytes.  That typecast works because a DWORD is 4 bytes and 'abcd' is 4 bytes too. 

OTH, FPC's typecasting rules are completely inconsistent (that's putting it _very_ kindly.)  If they were consistent then it would accept "SomeDword := DWORD('ab');" and "SomeDword := DWORD('abc');" because it accepts "SomeDword := DWORD('a');".  If the compiler was consistent  it would do the same padding it does for "DWORD('a') for the other cases but, it is NOT consistent.  Not only that, typecasts that are accepted for variables are not accepted for constants.  IOW, consistently inconsistent.

Also, it is not only wrong but totally ridiculous for FPC to accept "ABoolean32Var := boolean('abcd)';".  Obviously the compiler has no concept whatsoever of what a boolean is.  It sort of manages to implement C's BOOL and tries rather poorly to fit boolean into BOOL.  a BOOL and its variations are not limited to the value 0 and 1, but boolean is (is supposed to be but, obviously not in FPC.)

Maybe there is one thing we could all agree on which is: the type boolean is NOT the same as the type BOOL (at least it isn't supposed to be but, it is in FPC)

That FPC sees boolean to be the same as BOOL is patently obvious because it generates the same code for either which is preposterously wrong for boolean.  There is no boolean type in FPC.
« Last Edit: April 22, 2025, 04:00:34 pm by 440bx »
(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: 17423
  • Ceterum censeo Trumpum esse delendum (Tnx Charlie)
Re: Boolean type
« Reply #93 on: April 22, 2025, 03:59:29 pm »
Has there ever been a time where "cast" exclusively referred to bit pattern reinterpretation? (Genuine question)
Yes, since K&R I know it, but probably much earlier in CS.
Quote
In C, the standard way to convert between  int  and  double  is to use casts.
The C++ standard considers cast to be synonymous with explicit conversion. Furthermore,  std::bit_cast  isn't part of the core language; it's a standard library function.
The C++ approach is quite like the helpers.
Quote
(And by the way, "to cast" originally meant pouring molten metal into a mould, which also changes the metal's shape.)
No, it means shaping the same amount of material into a different shape. It comes from old Norse and means "to throw" but there are much earlier Greek references that describe the same concept. ( Looked that up: Metaphysics (Book VII, section 1033b) , Aristotle of course, should have known that  :'( )
Think a certain amount of clay turned into a brick.
The concept is also known as hylomorphism.
« Last Edit: April 22, 2025, 04:10:45 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11462
  • Debugger - SynEdit - and more
    • wiki
Re: Boolean type
« Reply #94 on: April 22, 2025, 04:20:22 pm »
OTH, FPC's typecasting rules are completely inconsistent (that's putting it _very_ kindly.)  If they were consistent then it would accept "SomeDword := DWORD('ab');" and "SomeDword := DWORD('abc');" because it accepts "SomeDword := DWORD('a');".  If the compiler was consistent  it would do the same padding it does for "DWORD('a') for the other cases but, it is NOT consistent.  Not only that, typecasts that are accepted for variables are not accepted for constants.  IOW, consistently inconsistent.

Yes there appear to be some inconsistencies. As the example with const section vs code section shows. But that isn't a statement on the concept itself.

As for DWORD('a'): 'a' is of type char (not some string) => that makes it an ordinal value, and afaik (need to double check) that introduces an conversion as part of the overall operation.

Try DWORD('a'+'') and you will see that it fails for a string (long or short $H+/-). Because a string has no ordinal value. And the wrong size in this case.



Yes the fact that you get automatic conversion thrown in there as part of some mix, all with one syntax... that is not always helping. But that is a new topic, way off the original statement.


Zoran

  • Hero Member
  • *****
  • Posts: 1949
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Boolean type
« Reply #95 on: April 22, 2025, 04:37:52 pm »
The auto conversion is indeed a problem and hell when you want to use C style casts.

Is it documented anywhere? When can we expect conversion instead of cast?

The work-around is using pointer types to what you want to cast.

Yes, that would be the first of these three workarounds:
Code: Pascal  [Select][+][-]
  1. // Workaround 1 - using pointer cast
  2. function CastInt64ToDouble_1(const N: Int64): Double; inline;
  3. begin
  4.   PInt64(@Result)^ := N;
  5. end;
  6.  
  7. // Workaround 2 - using move procedure
  8. function CastInt64ToDouble_2(const N: Int64): Double; inline;
  9. begin
  10.   system.Move(N, Result, SizeOf(Result));
  11. end;
  12.  
  13. // Workaround 3 - using absolute directive
  14. function CastInt64ToDouble_3(const N: Int64): Double; inline;
  15. var
  16.   ResultAsInt64: Int64 absolute Result;
  17. begin
  18.   ResultAsInt64 := N;
  19. end;
  20.  

The best way to show that is trying to translate any and all examples in the famous "bit twiddling hacks" from stanford.
https://graphics.stanford.edu/~seander/bithacks.html
Some of which need adjusting in FPC because of implicit conversions.

Thanks! See, I'm using one of their pearls (linked there in the comment). :)

This is known to the core compiler team.
But Delphi compatibility would be the priority... This mess came from Embarcadero, right?
« Last Edit: April 22, 2025, 04:41:49 pm by Zoran »
Swan, ZX Spectrum emulator https://github.com/zoran-vucenovic/swan

440bx

  • Hero Member
  • *****
  • Posts: 5586
Re: Boolean type
« Reply #96 on: April 22, 2025, 04:39:27 pm »
Try DWORD('a'+'') and you will see that it fails for a string (long or short $H+/-). Because a string has no ordinal value. And the wrong size in this case.
DWORD('a+') does NOT work but...
DWORD('a+++')  DOES work. 
Last I checked 'a+' and 'a+++' are both strings.  Therefore the fact that one is _not_ accepted and the other one _is_ can't have anything to do with being strings.   Could it be size by any chance ? ...

the fact is, if it accepts DWORD('a') and DWORD('a+++') then it should accept any string that is between 1 and 4 characters because it should do the same padding it is doing when it sees DWORD('a').

if it didn't accept DWORD('a') then and only then it would be justified in accepting only 4 character strings.



Here is a small example of how inconsistent FPC is when it comes to typecasting:
Code: Pascal  [Select][+][-]
  1.   b := boolean('a');  { no warning here, looks like 'a' is between 0 and 1            }
  2.   b := boolean($61);  { no warning here either $61 apparently is also between 0 and 1 }
  3.   b := boolean(512);  { Warning: range check error while evaluating constants (512 must be between 0 and 1) }
  4.  
the character 'a' apparently is between 0 and 1 because no warning is issued about the range.
the number $61 seems to also be between 0 and 1 because no warning is issued about the range.
the number 512 is NOT between 0 and 1 (good that it notices that.)

Maybe typecasting 'a' and $61 to boolean is "undefined territory" while typecasting 512 isn't.  That must be it.  'a' and $61 didn't make it into the contract but 512 fortunately did. That's a relief... at least some things made it.

Good thing there is strong type checking to warn the programmer that any number (or character) above 255 isn't between 0 and 1.   That is so informative and useful.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

Zoran

  • Hero Member
  • *****
  • Posts: 1949
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Boolean type
« Reply #97 on: April 22, 2025, 04:50:54 pm »
Maybe there is one thing we could all agree on

Never.

which is: the type boolean is NOT the same as the type BOOL (at least it isn't supposed to be but, it is in FPC)

This type is true whenever it is not zero, false only when it equals zero. Type Boolean if FPC is True only when it equals one. It is False only when it equals zero.

This is obviously different.
Swan, ZX Spectrum emulator https://github.com/zoran-vucenovic/swan

440bx

  • Hero Member
  • *****
  • Posts: 5586
Re: Boolean type
« Reply #98 on: April 22, 2025, 05:03:53 pm »
Type Boolean if FPC is True only when it equals one. It is False only when it equals zero.
But, that's not true.

In FPC a boolean that has any value other than 1 is TRUE which is very different than what it's supposed to be and very different than what is documented.

What you stated is what it's supposed to be and, it isn't remotely that way.  That's has been proved in quite a few ways by now.


(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: 11462
  • Debugger - SynEdit - and more
    • wiki
Re: Boolean type
« Reply #99 on: April 22, 2025, 05:35:19 pm »
Try DWORD('a'+'') and you will see that it fails for a string (long or short $H+/-). Because a string has no ordinal value. And the wrong size in this case.
DWORD('a+') does NOT work but...

Your copy differs. It isn't 'a+' => string with 2 chars.

I wrote 'a' +''  => joining with the empty string, to get a STRING with len=1 (rather than a char / which has no length).

You can do: ord('a')
But you can not do: ord('a' + '')
Nor ord('abc')


Zoran

  • Hero Member
  • *****
  • Posts: 1949
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Boolean type
« Reply #100 on: April 22, 2025, 05:40:42 pm »
In FPC a boolean that has any value other than 1 is TRUE

Wrong.
It is true only if it equals 1, false only when it equals zero, all other values are undefined.
If you find anything in fpc sources that doesn't comply with that, please (only then) report.
Swan, ZX Spectrum emulator https://github.com/zoran-vucenovic/swan

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11462
  • Debugger - SynEdit - and more
    • wiki
Re: Boolean type
« Reply #101 on: April 22, 2025, 05:51:47 pm »
Type Boolean if FPC is True only when it equals one. It is False only when it equals zero.
But, that's not true.

In FPC a boolean that has any value other than 1 is TRUE which is very different than what it's supposed to be and very different than what is documented.

No that is wrong

The ordinal (be that bit, word, integer...) => 0 is false
The ordinal (be that bit, word, integer...) => 1 is true

Everything else does not have a defined boolean state.

Of course if you compile "Boolean(2)" it will return one of the 2 states. But which of those 2 states is not defined. Even if all existing versions with all variations of all compile time settings would return the same state, this isn't guaranteed to persist for the future. It is fluke that it manifest of the one or other state. It is not defined.

If I use pen and paper, then I may write down 0 or 1 (or if agreed with my coworkers True/False) for the 2 states. But the paper still allows me to write 3 or Foo, and then it simply isn't valid anymore. I can not trust what my co-workers will do with those tokens.
Yet paper as storage allows the extra info => that does not invalidate the concept of boolean expressions written on Paper. What makes it "no longer boolean" is if I write down undefined tokens.

Using a bigger storage in a computer still is valid boolean. But If I poke something else (other than the defined states) into that storage, then it isn't boolean anymore.

You said yourself, there is no 3rd state. So if it isn't 0 or 1 then it is the same as "foo" on a piece of paper => not defined. But who knows what my coworker may read of it. They blindly trust me, that whatever I wrote will be correct. So they may see the leading "f" or they may recognise its the shorter of the 2 tokens. The outcome is not defined.


440bx

  • Hero Member
  • *****
  • Posts: 5586
Re: Boolean type
« Reply #102 on: April 22, 2025, 06:11:45 pm »
Wrong.

It is true only if it equals 1, false only when it equals zero, all other values are undefined.
You believe that ? ... I got a really good deal for you on a bridge in NY...

It has already been shown that FPC will consider any value other than 0 to be TRUE for a boolean.  That's not undefined territory, that's a FACT.  That's been proved, your wishful thinking doesn't change reality.

You and/or anyone else for that matter, can claim Santa Claus exists but, it doesn't make it that way.



@Martin,

The point remains the same, FPC can't tell a boolean from a dead duck.

It accepts DWORD('a') which it should not.  It should require ord('a') because of the size mismatch but, since it accepts that then it should also accept DWORD('ab') and DWORD('abc') but it doesn't.

The bottom line is this: FPC erroneously considers a boolean as a data type consisting of 8, 16, 32 or 64 bits which is an atrocity.  A boolean is a single bit.   The container is NOT the type.

Plus, it's patently wrong and absurd for the compiler to accept boolean(8) without any complaint whatsoever but complain about boolean(512).  That proves beyond any doubt, reasonable or otherwise, that FPC _incorrectly_ considers a boolean a byte/word/dword/qword sized type, when it is not.   

There is no boolean in FPC.  In FPC the boolean type is "undefined" and _unknown_ "territory".



I love Pascal but, it is no wonder it's on its way to the grave.  Some of it's developers (and some of its users) have no regard whatsoever for logical and mathematical correctness.  writable constants, boolean characters and strings, $61 is between 0 and 1, 0 is a signed numeral... etc, etc,
(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: 11462
  • Debugger - SynEdit - and more
    • wiki
Re: Boolean type
« Reply #103 on: April 22, 2025, 06:21:32 pm »
It has already been shown that FPC will consider any value other than 0 to be TRUE for a boolean.  That's not undefined territory, that's a FACT.  That's been proved, your wishful thinking doesn't change reality.

Really? I have not seen that proof.

What I have seen is statements in which undefined was confused with either true or false.

Mind "undefined" is not the same as null in sql. It doesn't have a predictable outcome. But it has an observable outcome. And once I observed, I can repeat if I keep the relevant parameters the same (and in some cases, the relevant parameters may currently not be change able, but that does not change that it is undefined to start with).

And before you say "boolean does only have 2 states, there is no undefined" => undefined here means that boolean no longer applies (even if the type still has that name). undefined means the type specific behaviour has been switched off.  (coincidences may happen, but they are coincidences).

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Boolean type
« Reply #104 on: April 22, 2025, 06:34:49 pm »
Is this conversion behaviour documented anywhere? Not a word about it in https://www.freepascal.org/docs-html/ref/refse85.html#x147-17100012.5 page.
operator overloading ?

Quote
How can we tell when it is not a cast but a conversion? Why wasn't assignment compatibility of Integer to Double good enough?
Basically you can't unless you know which ones are 'active'.

But Delphi compatibility would be the priority... This mess came from Embarcadero, right?
No matter who or what is responsible the compatibility does it and which renders these kind of discussions completely useless imho. But that compatibility is a joke on itself (sometimes intentional, sometimes by accident).
Today is tomorrow's yesterday.

 

TinyPortal © 2005-2018