Bookstore

Recent

Author Topic: Is there a "bitness dependent" boolean type in FPC ?  (Read 742 times)

440bx

  • Hero Member
  • *****
  • Posts: 1563
Is there a "bitness dependent" boolean type in FPC ?
« on: February 19, 2020, 07:06:31 pm »
Hello,

ptrint and ptruint change size depending on the target bitness and, that is often convenient.

I was wondering if there was a Boolean (ptrboolean ?) type that would also change in size depending on the target bitness and, that is my question, is there such a Boolean type in FPC ?

Thank you for your help.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8064
Re: Is there a "bitness dependent" boolean type in FPC ?
« Reply #1 on: February 19, 2020, 07:12:00 pm »
Boolean or Bool?

But since the boolean is not a variable type like pointer is, and always one byte, in practice it probably doesn't matter, contrary to languages that map boolean onto integer types.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 739
    • Lebeau Software
Re: Is there a "bitness dependent" boolean type in FPC ?
« Reply #2 on: February 19, 2020, 07:17:04 pm »
ptrint and ptruint change size depending on the target bitness and, that is often convenient.

The bitness size you refer to only applies to pointers.  PtrInt and PtrUInt exist to store pointers in integer types, so of course they have to adjust size to accommodate the correct size of a pointer.  But that makes no sense to do for a boolean.

I was wondering if there was a Boolean (ptrboolean ?) type that would also change in size depending on the target bitness

No.  Why do you need this?  A boolean is just a true/false value, so only 1 byte is needed for it.

If you really need a multi-byte boolean, there are several existing types available:

  • 2 bytes: WordBool and Boolean16
  • 4 bytes: LongBool and Boolean32
  • 8 bytes: QWordBool and Boolean64

But there is no existing type to match the bitness size of a pointer.  You will just have to create your own alias for that, eg:

Code: [Select]
{$IFDEF CPU32}
type
  PtrBoolean = Boolean32; // or LongBool
{$ENDIF}
{$IFDEF CPU64}
type
  PtrBoolean = Boolean64; // or QWordBool
{$ENDIF}
« Last Edit: February 19, 2020, 07:21:58 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

440bx

  • Hero Member
  • *****
  • Posts: 1563
Re: Is there a "bitness dependent" boolean type in FPC ?
« Reply #3 on: February 19, 2020, 07:58:18 pm »
Boolean or Bool?
As long as it changes size with the bitness, either would do. :)  Spandex Boolean ;)

<snip> contrary to languages that map boolean onto integer types.
that's exactly what I need at this time.  A pointer that can be interpreted as false if nil and true if not.

Thank you Marco.


The bitness size you refer to only applies to pointers.  PtrInt and PtrUInt exist to store pointers in integer types, so of course they have to adjust size to accommodate the correct size of a pointer.  But that makes no sense to do for a boolean.
It is quite convenient when the majority of the time, all that matters is knowing if the pointer is not nil and, dereferencing the pointer is needed only a few times.  In that case, defining a function's return value as "booleanptr" would be convenient.

No.  Why do you need this?  A boolean is just a true/false value, so only 1 byte is needed for it.
Because there is a function that most of the time, I only need to know if it found what I told it to search for (true/false) but, there are a very few times when it is necessary to inspect what it found.  Being able to interpret its Boolean return as a pointer to a structure to inspect its content would be quite convenient.


If you really need a multi-byte boolean, there are several existing types available:

  • 2 bytes: WordBool and Boolean16
  • 4 bytes: LongBool and Boolean32
  • 8 bytes: QWordBool and Boolean64
Yes, but I need a Boolean type that changes with the bitness because it is actually a pointer.

But there is no existing type to match the bitness size of a pointer.  You will just have to create your own alias for that, eg:

Code: [Select]
{$IFDEF CPU32}
type
  PtrBoolean = Boolean32; // or LongBool
{$ENDIF}
{$IFDEF CPU64}
type
  PtrBoolean = Boolean64; // or QWordBool
{$ENDIF}
That's what I did. 

Thank you Remy.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 739
    • Lebeau Software
Re: Is there a "bitness dependent" boolean type in FPC ?
« Reply #4 on: February 19, 2020, 08:13:04 pm »
that's exactly what I need at this time.  A pointer that can be interpreted as false if nil and true if not.

That is not how things work.  And you seem to have a fundamental misunderstanding of what bools and pointers actually are and how they work.

If you need to know if a pointer is nil, just compare it directly:

Code: [Select]
if pointer = nil then
Code: [Select]
if pointer <> nil then
The '=' and '<>' operators return an actual Boolean, no conversion needed.

It is quite convenient when the majority of the time, all that matters is knowing if the pointer is not nil and, dereferencing the pointer is needed only a few times.  In that case, defining a function's return value as "booleanptr" would be convenient.

That makes no sense whatsoever.  A Pointer-to-boolean is not the same thing as a Pointer-sized-boolean.  Two completely different things.

Because there is a function that most of the time, I only need to know if it found what I told it to search for (true/false) but, there are a very few times when it is necessary to inspect what it found.  Being able to interpret its Boolean return as a pointer to a structure to inspect its content would be quite convenient.

You are confused.  What you NEED to do is return an ACTUAL POINTER to the data that was found.  If nothing was found, return a nil pointer.  The CALLER can then check if the pointer is nil or not, and if not then dereference it if needed.  Converting the pointer to a boolean is NOT what you want, especialy for those few times where you WANT to inspect the data.  Converting the pointer, you lose access to the data.

And besides, you DO NOT need to convert the pointer to a pointer-sized boolean in this situation anyway.  Just because you need to work with a pointer to data does not mean you have to work with a pointer-sized boolean, too.

Code: [Select]
function Find(params): Pointer;
begin
  ...
  if (found) then
    Result := pointer to data
  else
    Result := nil;
end;

...

if Find(params) <> nil then
begin
  // found, do something...
end else
begin
  // not found, do something else...
end;

...

var
  data: Pointer;

data := Find(params);
if data <> nil then
begin
  // found, use data as needed...
end else
begin
  // not found, do something else...
end;

Alternatively, if you really don't need the data pointer most of the time, just do this instead:

Code: [Select]
function Find(params; var Data: Pointer): Boolean; overload;
begin
  ...
  if (found) then begin
    Data := pointer to data;
    Result := True;
  end else
    Result := False;
end;

function Find(params): Boolean; overload;
var
  Ignore: Pointer;
begin
  Result := Find(params, Ignore);
end;

...

if Find(params) then
begin
  // found, do something...
end else
begin
  // not found, do something else...
end;

...

var
  data: Pointer;

if Find(params, data) then
begin
  // found, use data as needed...
end else
begin
  // not found, do something else...
end;

You are making things more complicated than they need to be.

Yes, but I need a Boolean type that changes with the bitness because it is actually a pointer.

No, you really don't.
« Last Edit: February 19, 2020, 08:16:57 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

440bx

  • Hero Member
  • *****
  • Posts: 1563
Re: Is there a "bitness dependent" boolean type in FPC ?
« Reply #5 on: February 19, 2020, 10:44:44 pm »
If you need to know if a pointer is nil, just compare it directly:
That's what I don't want to have to do.   The great majority of the time, all I need is to know if the entry in the table was found, I don't need to inspect the entry.

I'm used to the way it's done in C.  That's what I'd like to have, just test without having to type "= nil" or "<> nil" all the time,  just because, on rare occasions I need to use the pointer.

No, you really don't.
Yes, I do. :)

The workaround you suggested works.  I defined a TNATIVE_BOOLEAN that changes size with the bitness and I "absolute" a pointer on top of that when I need to inspect the entry.  It's pedestrian and not elegant but, it gets the job done.

using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

jamie

  • Hero Member
  • *****
  • Posts: 2461
Re: Is there a "bitness dependent" boolean type in FPC ?
« Reply #6 on: February 19, 2020, 11:09:41 pm »
You are looking for something that will never happen in FPC, because I've asked for a few times and all I get is flack about it..

All types without any Boolean expressions or otherwise should default to a Boolean expression if these are types, not functions etc..

 In your case..

If SomePointer then ….

or

 If Not SomePointer then....

Basically, being any form of a number type or pointer can be tested for a 0 value to indicate if it's tree of false, false for 0 / Nil otherwise true for all other values

 I don't know if there are helpers for pointers, maybe there should be if not but with other numerical types you do have this..

 If SomeInteger.ToBoolean then....

So my question here is , why can't we do this..

 If SomeInteger then.....

 Oh well, I understand the frustration that comes with it.

 you can do this however,.

If Boolean(SomePotiner) then the compiler may decide to only examine the low byte and so on..

But I think making a pointer helper adding to one for a bool is a good idea and the helper should also be able to auto detect a Boolean operation if there is nothing defind..
for example

 if SomePointer then..

 In the helper there would be a default call of returning a Boolean results or inline generated code.

The proper way to do this is at the compiler intrinsic level where the compiler can property code it without the over head..

 Maybe if we ask enough we could get it ;)

Number 1 at blue screen app creations!

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8064
Re: Is there a "bitness dependent" boolean type in FPC ?
« Reply #7 on: February 19, 2020, 11:16:01 pm »
If you need to know if a pointer is nil, just compare it directly:
That's what I don't want to have to do.   The great majority of the time, all I need is to know if the entry in the table was found, I don't need to inspect the entry.

I'm used to the way it's done in C.  That's what I'd like to have, just test without having to type "= nil" or "<> nil" all the time,  just because, on rare occasions I need to use the pointer.

Be very careful then. For Boolean types, all values except 0 and 1 are undefined, so they might return false even when not 0.  It might be translated to "test  eax,1" or so, so all even values would be false, and all odd values would be true.

Assuming other languages constructs port over to the same semantics is not a wise thing to do. The boolean<-> integer <-> pointer equivalence is much weaker in Pascal than in C.
« Last Edit: February 19, 2020, 11:18:39 pm by marcov »

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 739
    • Lebeau Software
Re: Is there a "bitness dependent" boolean type in FPC ?
« Reply #8 on: February 19, 2020, 11:35:17 pm »
The great majority of the time, all I need is to know if the entry in the table was found, I don't need to inspect the entry.

Then you should write your search function to return a standard Boolean.  You don't need a pointer-sized Boolean, that is just a waste of memory.

I'm used to the way it's done in C.  That's what I'd like to have, just test without having to type "= nil" or "<> nil" all the time

C does an implicit conversion from a pointer to a bool for you in contexts where a bool is expected, like in an 'if' statement.  Pascal simply does not work that way, pointer comparisons must be done explicitly.

just because, on rare occasions I need to use the pointer.

Then you should just return a pointer and compare it explicitly.  Without using some kind of separation of bool and data, like I showed you in my previous reply, another option is something like this, which is just nuts:

Code: [Select]
{$IFDEF CPU32}
type
  BooleanPtr = LongBool;
{$ENDIF}
{$IFDEF CPU64}
type
  BooleanPtr = QWordBool;
{$ENDIF}

function Find(params): Pointer;
begin
  ...
  if (found) then
    Result := pointer to data
  else
    Result := nil;
end;

...

//if Find(params) <> nil then
if BooleanPtr(Find(params)) then
begin
  // found, do something...
end else
begin
  // not found, do something else...
end;

...

var
  data: Pointer;

data := Find(params);
//if data <> nil then
if BooleanPtr(data) then
begin
  // found, use data as needed...
end else
begin
  // not found, do something else...
end;

No, you really don't.
Yes, I do. :)

No, you really don't.  You are just being lazy, making your code require more typing and be uglier and harder to maintain.
« Last Edit: February 19, 2020, 11:40:20 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 739
    • Lebeau Software
Re: Is there a "bitness dependent" boolean type in FPC ?
« Reply #9 on: February 19, 2020, 11:38:12 pm »
you can do this however,.

If Boolean(SomePotiner) then the compiler may decide to only examine the low byte and so on..

Which won't work for non-nil pointers whose low byte happens to be 0.
« Last Edit: February 19, 2020, 11:41:53 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

winni

  • Hero Member
  • *****
  • Posts: 1114
Re: Is there a "bitness dependent" boolean type in FPC ?
« Reply #10 on: February 19, 2020, 11:52:56 pm »
Hi!

Make it save and crazy:

Code: Pascal  [Select]
  1. if boolean (odd(Qword(MyPointer))) then

Winni

440bx

  • Hero Member
  • *****
  • Posts: 1563
Re: Is there a "bitness dependent" boolean type in FPC ?
« Reply #11 on: February 20, 2020, 12:52:40 am »
It might be translated to "test  eax,1" or so, so all even values would be false, and all odd values would be true.
I checked that, it does a "test reg, reg"

Assuming other languages constructs port over to the same semantics is not a wise thing to do.
I couldn't agree anymore, which is why I asked if some type worked just as BOOL does in C.



You are just being lazy, making your code require more typing and be uglier and harder to maintain.
I'm not being lazy.  It doesn't make much sense to me to change about a hundred calls because less than 5 of them require the pointer.  It's the tail wagging the dog.

This case has no solution I like.  It's this kind of stuff that reminds me why I still use C in spite of the fact that I strongly dislike it.

using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

jamie

  • Hero Member
  • *****
  • Posts: 2461
Re: Is there a "bitness dependent" boolean type in FPC ?
« Reply #12 on: February 20, 2020, 03:38:41 am »
I feel your pain, really  >:(

 The compiler should at least allow a helper to have a default sub member call to allow us short hand coders to implement such behavior. Or just put in there !

  I can picture the key word "DEFAULT" being used in a type helper to  have it excute a ToBoolean expression. Or just simply inline the equation..

 If SomePointer then..

 would end up being

 If SomePointer <> Nil then...

 Or
 If SomePointer.ToBoolean then..

 but in the Type define record for the ToBoolean section, just put a DEFAULT at the end.

of course the compiler needs to be updated to do this.. I've already tried this and it does not work  >:(

The same goes for other types like Managed types..

If SomeString then....
would generate code like

If SomeString <> '' Then ….
etc..

But this should only work when ever Boolean expressions are applicable.

I don't really see the issue here because if you use a function with a Boolean results you don't need to do this

If SomeFunction = True then...

So where we are in the modern days of coding and this is what we live with..

I like C for somethings but object syntax still beats it, it would be a lot nicer of we could just merge some more good ideas from C into this .
Number 1 at blue screen app creations!

Thaddy

  • Hero Member
  • *****
  • Posts: 9784
Re: Is there a "bitness dependent" boolean type in FPC ?
« Reply #13 on: February 20, 2020, 09:00:47 am »
Since 3.0 true and false are not keywords anymore, so you can do things like this (on a per unit basis or qualified with a unit prefix:
Code: Pascal  [Select]
  1. {$mode delphi}{$H+}
  2. const
  3.   false = nil;
  4.   true = not PtrUint(false); // needs a cast, of course
  5.  // you can also make sure like : Pointer(not PtrUint(false))
  6. begin
  7. end.
If this is useful? dunno, but it works... Now true and false are pointer types..... :D
(Rather proud of this......silly solution...)
https://wiki.freepascal.org/User_Changes_3.0#True_and_False_are_not_keywords_anymore
[edit]
To my surprise this actually works!
« Last Edit: February 20, 2020, 09:41:52 am by Thaddy »
I am more like donkey than shrek

PascalDragon

  • Hero Member
  • *****
  • Posts: 1092
  • Compiler Developer
Re: Is there a "bitness dependent" boolean type in FPC ?
« Reply #14 on: February 20, 2020, 10:08:28 am »
Assuming other languages constructs port over to the same semantics is not a wise thing to do.
I couldn't agree anymore, which is why I asked if some type worked just as BOOL does in C.

Be sure to use LongBool and QWordBool then. Using Boolean32 and Boolean64 would lead to trouble in your context sooner or later.

You are just being lazy, making your code require more typing and be uglier and harder to maintain.
I'm not being lazy.  It doesn't make much sense to me to change about a hundred calls because less than 5 of them require the pointer.  It's the tail wagging the dog.

This case has no solution I like.  It's this kind of stuff that reminds me why I still use C in spite of the fact that I strongly dislike it.

Declaring your own alias is the solution. PtrInt and PtrUInt are declared like that as well, so there is nothing inherently wrong with that.