Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2022-08

BoolToStr

13 messages · 8 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

James Richters

I'm generating a report where I wish to display some Boolean values. I thought I would try BoolToStr, as according to:
https://www.freepascal.org/docs-html/rtl/sysutils/booltostr.html it states:

Description
BoolToStr converts the boolean B to one of the strings 'TRUE' or 'FALSE'

So it should do exactly what I want. output the text string 'TRUE' or 'FALSE' depending on the Boolean state,
but that is not what happens:

Uses Sysutils;
Begin
Writeln(BooltoStr(True));
Writeln(BooltoStr(False));
End.

Running "i:\booltostr.exe "
-1
0

Why true is -1 instead of 1 is beyond me, but anyway, I would consider this BoolToInt, not BoolToStr, I want the Strings 'TRUE' or 'FALSE' as indicated in the documentation

And BoolToInt should always output 0 or 1, not matter what operating system you are on.. I don't understand the -1. I guess some Windows API's use -1 for true.. I still don't understand.
Maybe there should be a BoolToBit that could always be 0 or 1 regardless of the operating system.

I know I can write my own simple function to do it the way I want, but why does this behavior not match the documentation?
The whole point of having lots of little functions like FloatToStr, is so everyone doesn't have to keep writing the same functions over and over.

James

Reply by email

Michael Van Canneyt
to James Richters
James Richters wrote 24 lines
I'm generating a report where I wish to display some Boolean values. I thought I would try BoolToStr, as according to: https://www.freepascal.org/docs-html/rtl/sysutils/booltostr.html it states: Description BoolToStr converts the boolean B to one of the strings 'TRUE' or 'FALSE' So it should do exactly what I want. output the text string 'TRUE' or 'FALSE' depending on the Boolean state, but that is not what happens: Uses Sysutils; Begin Writeln(BooltoStr(True)); Writeln(BooltoStr(False)); End. Running "i:\booltostr.exe " -1 0 Why true is -1 instead of 1 is beyond me, but anyway, I would consider this BoolToInt, not BoolToStr, I want the Strings 'TRUE' or 'FALSE' as indicated in the documentation

I will adapt the documentation to be more precies.

You can use

BoolToStr(b,'TRUE','FALSE')

or
BoolToStr(b,True)

in which case it will use the BoolStrs arrays to determine the strings.

-1 and 0 are the Delphi values, which, I agree, are not very intuitive.

Show quoted text 6 lines
And BoolToInt should always output 0 or 1, not matter what operating system you are on.. I don't understand the -1. I guess some Windows API's use -1 for true.. I still don't understand. Maybe there should be a BoolToBit that could always be 0 or 1 regardless of the operating system.

As said, the 0 and -1 are for Delphi compatibility.

Use

Ord(Boolean)

It will give you 0 and 1.

Michael.

Reply by email

Ralf Quint
to James Richters: I'm generating a report where I wish to display some Boolean values. I thought I would…
James Richters wrote 10 lines
Running "i:\booltostr.exe " -1 0 Why true is -1 instead of 1 is beyond me, but anyway, I would consider this BoolToInt, not BoolToStr,I want the Strings ‘TRUE’ or ‘FALSE’ as indicated in the documentation

Very logical in fact. 0 is NO bit set in any given size of boolean data type, -1 means ALL bits set on that same size boolean data type. And a check on TRUE or FALSE, can easily be done with checking the sign flag of a processor rather than doing actually any bit fiddling (at least on those CPUs that I am familiar with).

Ralf

Reply by email

James Richters
to Michael Van Canneyt: I will adapt the documentation to be more precies. You can use BoolToStr(b,'TRUE','FALSE')
You can use

BoolToStr(b,'TRUE','FALSE')

That works great! Shouldn't that be the default and you can put in something else if you want it? It's Boolean To String... not Bool to some number.
If I just do Writeln(True); I get the string 'TRUE' The text 'TRUE' is what you get if you convert a Boolean value of 1 to a string, not anything else.

I guess the default must have been 'TRUE' or 'FALSE' at one time as that is how the documentation is written, it must have been changed to be compatible with Delphi code at some point I guess.

Thanks for the suggestion, it works for my needs.

James.

Earlier message 68 lines
-----Original Message----- From: fpc-pascal On Behalf Of Michael Van Canneyt via fpc-pascal Sent: Sunday, August 28, 2022 11:39 AM To: ; FPC-Pascal users discussions Cc: Michael Van Canneyt ; James Richters Subject: Re: [fpc-pascal] BoolToStr On Sun, 28 Aug 2022, James Richters via fpc-pascal wrote: > I'm generating a report where I wish to display some Boolean values. > I thought I would try BoolToStr, as according to: > https://www.freepascal.org/docs-html/rtl/sysutils/booltostr.html it states: > > Description > BoolToStr converts the boolean B to one of the strings 'TRUE' or 'FALSE' > > So it should do exactly what I want. output the text string 'TRUE' or > 'FALSE' depending on the Boolean state, but that is not what happens: > > Uses Sysutils; > Begin > Writeln(BooltoStr(True)); > Writeln(BooltoStr(False)); > End. > > Running "i:\booltostr.exe " > -1 > 0 > > Why true is -1 instead of 1 is beyond me, but anyway, I would consider > this BoolToInt, not BoolToStr, I want the Strings 'TRUE' or 'FALSE' > as indicated in the documentation I will adapt the documentation to be more precies. You can use BoolToStr(b,'TRUE','FALSE') or BoolToStr(b,True) in which case it will use the BoolStrs arrays to determine the strings. -1 and 0 are the Delphi values, which, I agree, are not very intuitive. > > And BoolToInt should always output 0 or 1, not matter what operating > system you are on.. I don't understand the -1. I guess some Windows > API's use -1 for true.. I still don't understand. > Maybe there should be a BoolToBit that could always be 0 or 1 > regardless of the operating system. As said, the 0 and -1 are for Delphi compatibility. Use Ord(Boolean) It will give you 0 and 1. Michael.

Reply by email

Marco van de Voort
to Ralf Quint: Very logical in fact. 0 is NO bit set in any given size of boolean data type, -1 means…

Op 8/28/2022 om 8:45 PM schreef Ralf Quint via fpc-pascal:

Show quoted text 14 lines
On 8/28/2022 8:23 AM, James Richters via fpc-pascal wrote: > Running "i:\booltostr.exe " > > -1 > > 0 > > Why true is -1 instead of 1 is beyond me, but anyway, I would > consider this BoolToInt, not BoolToStr,I want the Strings ‘TRUE’ or > ‘FALSE’ as indicated in the documentation > Very logical in fact. 0 is NO bit set in any given size of boolean data type, -1 means ALL bits set on that same size boolean data type.

Pascal boolean datatypes only have 0 or 1 as defined values.  But probably it is for some COM or Winapi compatible purpose.

Reply by email

James Richters
to Marco van de Voort

I don't see how it makes anything compatible at all.. because it's NOT a 0 or a -1 integer value, it's a STRING of '0' or '-1' so you can't even evaluate the negative bit.. because there isn't one, it's a string of - and 1. You would have to do StrToInt(BoolToStr(MyVariable)) to be able to evaluate the negative bit... which again is useless because there is only one bit to check.. indeed you would need to do StrToInt(BoolToStr(MyVariable)) just to evaluate the 0 as a numeric value, but then this is a really round about way to do it when you could make a simple BoolToInt function to just give you the numeric result.

Even if it is convenient to set the - flag for "All Bits Set"  it doesn't apply to BoolToStr, because we aren't evaluating a Nibble, or a Byte, or a Word, etc, we are only evaluating a single bit Boolean variable.. so there are no, ALL Bits, there is only THE Bit.  I guess technically ALL one of it was set... but making it a -1 makes it more difficult to stack a bunch of these bits together into a word or something, and the - really serves no purpose if there is only one bit.. in fact you can't even put it into a byte because -1 isn't a valid Byte.  You would have to do MyByte:=Abs(StrToInt(BoolToStr(True)));

I think it would be best to make BoolToStr always produce 'TRUE' or 'FALSE' as the default because that is what is documented, and that is also what makes the most sense.. after all you are asking for a STRING, so you are outputting to something that wants a String, probably to be readable at some point, if you do Writeln of a Boolean you get 'TRUE' or 'FALSE', and BoolToStr should do that same thing... just like the documentation indicates.

An additional BoolToInt could be added that returned an integer, which I think should return a 0 or a 1, but maybe retain the ability to customize the integer output the same way BoolToStr does, then if you want to check the - flag instead of checking the 1 bit, you could do that.. as silly as it is for a 1 bit test.

Anyway, I suppose such a change would break a whole pile of stuff at this point, so it's probably not going to happen... but it would be nice if it made more logical sense, and BoolToInt is what you need if you want to get a 0 and 1 (or 0 and -1 as the case may be) numerical value, but there doesn't appear to be one in FPC.

I'm curious if there is a way to search the FPC version history of changes for BoolToStr to see why it was changed, and see if there is a valid reason not to change it back. it was obviously changed from the way the documentations is at some point. It really seems to me that if it was that important that someone had a function that output a 0 or a -1, the only way it makes sense is if it's an integer, not a string.

If a special function is needed for some COM thing or weird Winapi thing, then that function should be part of the unit that needs it, not modifying the generic function intended to be used for general purpose applications output something that does not conform to other Pascal Boolean datatypes and just confuses everyone.

James

Op 8/28/2022 om 8:45 PM schreef Ralf Quint via fpc-pascal: On 8/28/2022 8:23 AM, James Richters via fpc-pascal wrote: Running "i:\booltostr.exe "
-1
0

Why true is -1 instead of 1 is beyond me, but anyway, I would consider this BoolToInt, not BoolToStr, I want the Strings ‘TRUE’ or ‘FALSE’ as indicated in the documentation Very logical in fact. 0 is NO bit set in any given size of boolean data type, -1 means ALL bits set on that same size boolean data type. Pascal boolean datatypes only have 0 or 1 as defined values. But probably it is for some COM or Winapi compatible purpose.

Reply by email

Sven Barth
to James Richters
James Richters wrote
I'm curious if there is a way to search the FPC version history of changes for BoolToStr to see why it was changed, and see if there is a valid reason not to change it back. it was obviously changed from the way the documentations is at some point. It really seems to me that if it was that important that someone had a function that output a 0 or a -1, the only way it makes sense is if it's an integer, not a string.

This was done in 2006 (commit
https://gitlab.com/freepascal.org/fpc/source/-/commit/4264f5d0414 ) for Delphi compatibility and thus there is *no valid reason* to change it back.

Regards,
Sven

Reply by email

Michael Van Canneyt
to James Richters: I don't see how it makes anything compatible at all.. because it's NOT a 0 or a -1…
James Richters wrote 6 lines
I'm curious if there is a way to search the FPC version history of changes for BoolToStr to see why it was changed, and see if there is a valid reason not to change it back. it was obviously changed from the way the documentations is at some point. It really seems to me that if it was that important that someone had a function that output a 0 or a -1, the only way it makes sense is if it's an integer, not a string.

The reason is Delphi compatibility.

Michael.

Reply by email

Jean SUZINEAU
to James Richters: I don't see how it makes anything compatible at all.. because it's NOT a 0 or a -1…

Le 29/08/2022 à 01:41, James Richters via fpc-pascal a écrit :

If a special function is needed for some COM thing or weird Winapi thing, then that function should be part of the unit that needs it, not modifying the generic function intended to be used for general purpose applications output something that does not conform to other Pascal Boolean datatypes and just confuses everyone.

Unfortunately, it's not just a few windows functions which use this behaviour but the whole Windows API:

https://docs.microsoft.com/fr-fr/windows/win32/api/winuser/nf-winuser-getmessage?redirectedfrom=MSDN

The Microsoft BOOL datatype uses this convention so the whole ecosystem is attracted to use it (other C program on windows, Delphi, ... )

I imagine it's more efficient at the assembler level to process the result of functions returning boolean.

Reply by email

Nikolay Nikolov
to Jean SUZINEAU
Jean SUZINEAU wrote 18 lines
Le 29/08/2022 à 01:41, James Richters via fpc-pascal a écrit : > If a special function is needed for some COM thing or weird Winapi > thing, then that function should be part of the unit that needs it, > not modifying the generic function intended to be used for general > purpose applications output something that does not conform to other > Pascal Boolean datatypes and just confuses everyone. Unfortunately, it's not just a few windows functions which use this behaviour but the whole Windows API: https://docs.microsoft.com/fr-fr/windows/win32/api/winuser/nf-winuser-getmessage?redirectedfrom=MSDN The Microsoft BOOL datatype uses this convention so the whole ecosystem is attracted to use it (other C program on windows, Delphi, ... ) I imagine it's more efficient at the assembler level to process the result of functions returning boolean.

Or, it could be related to the (Visual) BASIC language. BASIC represents false as 0 and true as -1, and Microsoft have been a major developer of BASIC interpreters and compilers ever since their beginning. My guess is, they used -1 to ensure better interoperability between Visual C++ and Visual Basic.

Nikolay

Reply by email

James Richters
to Nikolay Nikolov

Thanks for the discussion everyone, it does shed some light on what's going on. I agree it would be impossible to change it now, It was actually a GREAT idea to make it customizable, and that serves my needs just fine. I guess all that's left is to update the documentation to show what it really does and show how it is customizable. I wouldn't mind doing that... if I knew how. What is the proper method to submit documentation change requests?

James

Reply by email

Michael Van Canneyt
to James Richters
James Richters wrote 7 lines
Thanks for the discussion everyone, it does shed some light on what's going on. I agree it would be impossible to change it now, It was actually a GREAT idea to make it customizable, and that serves my needs just fine. I guess all that's left is to update the documentation to show what it really does and show how it is customizable. I wouldn't mind doing that... if I knew how. What is the proper method to submit documentation change requests?

I already updated the documentation.

Will be visible tomorrow in the daily snapshot of the docs.

However, for future reference:
The proper procedure is to submit a patch in the issue tracker: https://gitlab.com/freepascal.org/fpc/documentation (if you look at the last commit on that page, you'll see it is the update of BoolToStr)

Michael.

Reply by email

Zeljko Avramovic
to James Richters: BoolToStr(b,'TRUE','FALSE') That works great! Shouldn't that be the default and you can…
Show quoted text 6 lines
> You can use BoolToStr(b,'TRUE','FALSE') That works great! Shouldn't that be the default and you can put in something else if you want it?

Latest trunk allows you this if you include new syshelpers unit:

True.ToString;                                          // True
True.ToTrueFalseString(scfUpperCase);                   // TRUE
True.ToString('OnState', 'OffState');                   // OnState
True.ToString('Running', 'Stopped', scfUpperCase);      // RUNNING

It also allows you to populate TBitFormatSettings with your strings for TRUE and FALSE and gives you method CopyToDefaultBoolStrings. This changes boolean to string text outputs in syshelpers and some other places. Maybe that could fit your bill.

More info can be found in this demo:
https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/rtl-objpas/examples/syshelpersdemo.pas

Reply by email