Recent

Author Topic: strange FPC error message  (Read 6328 times)

Thaddy

  • Hero Member
  • *****
  • Posts: 18764
  • To Europe: simply sell USA bonds: dollar collapses
Re: strange FPC error message
« Reply #15 on: June 08, 2020, 03:53:37 pm »
It would well be satisfied, if True would be represented by all numeric values with an even number of bits that are 1. And false with an odd number of bits that are one. That definition would work perfectly well. It does not do what C does, but so what?

That's not quite right, is it? Since, per definition, they have to maintain the relations:
Ord(False) < Ord(True)
Succ(False) = True ==> Pred(True) = False


Or am I wrong?
Nope.... :D ;D ;D that's a really good one.. ::)
« Last Edit: June 08, 2020, 03:56:19 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12177
  • Debugger - SynEdit - and more
    • wiki
Re: strange FPC error message
« Reply #16 on: June 08, 2020, 04:40:00 pm »
I made a lot of points, some of them are moot in the light of "Ah, I get your point.... But " part of my answer....
It is the same as TWeekDay(999).
That flies in the face of strong type checking.  The compiler should not allow a statement like that.

FPC is too cavalier when it comes to enforcing ranges.  Even Delphi, which is definitely on the loose side, is not as loose as FPC.  For instance, Delphi will _not_ allow indexing an array with a constant value that is out of range whereas FPC will (and it shouldn't.)
ok, so that is what causes the problem.
According to your "how it should be", Fpc should also not allow "Boolean(5)".

However, once we accept that it does, the result of the comparison in your example is known to be undefined, and there is no "logic in wonderland" at all. Once you leave the valid scope, behaviour does not have to be defined.

If your point is: You dislike type-casting (at least the way it currently happens to be) => well, you can make that point.

Quote
- 1, 3, 5 or whatever are all boolean values
No, they are not. 
Thanks for quoting this out of context :(
The above is a representation of my understanding of what you said (I did actually say the exact opposite).

Glad, I misunderstood you ... Good you clarified that they are not (and neither are 0 or 1).

But if those values are not boolean values, why should your example code work?
By typecasting them into boolean, you acknowledge that you mess up the underlying data in the boolean var. It no longer contains the binary representation for true, nor for false. So, as I said, it leads to undefined behaviour.

Yes, I understand, you would rather that typecast was not allowed.
But, if that is the problem you want to point out, why - in your example code - do you not point to the line with the timecast? Why do you highlight the comparison line by using a text like "(logic in wonderland)"?
The comparison line is entirely without flaw. It is undefined. It is so because of the typecast (which you may find "a bad idea" or "flawed" or ...)

IMHO, you are pointing to the wrong line.

Quote
You clearly expect the behaviour of longbool. So use that.
What I'd like, not what I expect since I know that won't happen, is for boolean to be logically correct.  That is, when a boolean variable A is true and another boolean variable B is true then A = B is true as well.
Ah, I get your point.... But

Code: Pascal  [Select][+][-]
  1.    writeln('a = ', a);
  2.    writeln('b = ', b);
  3.  
Then of course
Code: Pascal  [Select][+][-]
  1. if a = b then foo;
Should go to Foo.

But that ONLY applies, if the printed result of
    writeln('a = ', a);
is the result of defined behaviour.

In your example code
   writeln('a = ', a);
already is undefined behaviour (because a is neither true, nor false, and Pascal (unlike javascript) does not know undefined, not even null)

So the printed result of the writeln is just random.
If however the result of the writeln happens to be random/undefined, then it is consistent that the result of the comparison is too.

Quote
In FPC and Delphi boolean is sometimes boolean and sometimes C BOOL.
The undefined behaviour just currently coincides with  C BOOL. Does not mean it is the same....

Quote
the way it's documented is incorrect. 
Different issue.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12177
  • Debugger - SynEdit - and more
    • wiki
Re: strange FPC error message
« Reply #17 on: June 08, 2020, 04:43:49 pm »
It would well be satisfied, if True would be represented by all numeric values with an even number of bits that are 1. And false with an odd number of bits that are one. That definition would work perfectly well. It does not do what C does, but so what?

That's not quite right, is it? Since, per definition, they have to maintain the relations:
Ord(False) < Ord(True)
Succ(False) = True ==> Pred(True) = False


Or am I wrong?
In Pascal, yes.

I was referring to the general fact, that we tend to use "zero" vs either "one" or "none zero" as the way to represent bool values in computer memory.

Off course: Convenient.
  But nothing in the field of boolean algebra somehow mandates that the representation has to be that way. Inventing a different representation would not be wrong, in the sense that it breaks something that is mandated by the underlying concept.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12177
  • Debugger - SynEdit - and more
    • wiki
Re: strange FPC error message
« Reply #18 on: June 08, 2020, 05:45:48 pm »
Inconsistency and, the way it's documented is incorrect.  From the link given by @Kays,
Code: Text  [Select][+][-]
  1. Name         Size       Ord(True)
  2. Boolean         1       1
  3. Boolean8        1       1
  4. ByteBool        1       Any nonzero value
  5.  
The sample program I posted clearly shows that FPC (and Delphi) treat boolean the same as ByteBool, i.e, any non-zero value is true
I didn't answer that before, ...
Now had a brief look at the docs.

Where does your application "shows that FPC (and Delphi) treat boolean the same as ByteBool, i.e, any non-zero value is true" ?

I see "writeln('a=',a);
And as far as I can see, that statement has undefined behaviour.
It may print "true", but that is not in contradiction with it being undefined.

In fact look at my "bitpacked" example. And assigning "x.a := boolean(2)", will lead to the writeln returning switching between printing true or false. So clearly undefined behaviour.

Yes, I know the "ord value" also changes: 0 or 2. But that just shows, that after the typecast "boolean(2)" the entire behaviour becomes undefined.
« Last Edit: June 08, 2020, 05:50:42 pm by Martin_fr »

440bx

  • Hero Member
  • *****
  • Posts: 6130
Re: strange FPC error message
« Reply #19 on: June 08, 2020, 06:18:26 pm »
According to your "how it should be", Fpc should also not allow "Boolean(5)".
Correct.  That doesn't make sense because a boolean value can only have two values, true and false, which are supposed to be 1 and 0 respectively so they fit in _one_ bit.

FPC and Delphi allowing boolean(5) creates a type (which is not a genuine boolean) that cannot be represented with one bit, therefore cannot be bitpacked, therefore isn't a boolean.

IOW, the behavior and semantics of boolean types should remain the same whether they are packed or unpacked.

However, once we accept that it does, the result of the comparison in your example is known to be undefined, and there is no "logic in wonderland" at all.
No, the result isn't undefined because FPC _consistently_ will consider zero (0) as false and _not zero_ as true, which is _not_ the definition of a boolean.

Accepting booleans with a value of 5 (or some other value that is neither zero (0) nor one (1)) is like accepting square circles. 

Once you leave the valid scope, behaviour does not have to be defined.
That argument doesn't work because FPC is very consistent in considering "not zero" as true and "zero" as false.  That seems to be rather well defined. 

If your point is: You dislike type-casting (at least the way it currently happens to be) => well, you can make that point.
My point is: I dislike invalid typecasts such as boolean(5) which is as wrong as typecasting a null terminated array[11..2017] of char to an integer.  The numeral 5 doesn't fit in one bit anymore than that array fits in an integer.


Thanks for quoting this out of context :(
It wasn't my intention.  I missed the point you were making.

But if those values are not boolean values, why should your example code work?
The compiler should not allow a typecast "boolean(5)" because it knows that the numeral 5 cannot be represented with a single on/off instrument.

By typecasting them into boolean, you acknowledge that you mess up the underlying data in the boolean var. It no longer contains the binary representation for true, nor for false. So, as I said, it leads to undefined behaviour.
If the behavior was really undefined then it would not be predictable yet, it is rather predictable that any value other than zero is considered true, therefore it is not undefined, it is simply incorrect.

Yes, I understand, you would rather that typecast was not allowed.
Correct. :)

Why do you highlight the comparison line by using a text like "(logic in wonderland)"?
because the compiler consistently states that a non zero value is logically true but when two logically true values are compared, it says they are not equal.  If two values are logically equal (true) then the compiler cannot claim they are logically different.    The problems stems from the fact that it uses an arithmetic operation (an arithmetic comparison) to determine equality on logical types.  That's inherently incorrect. 

The undefined behaviour just currently coincides with  C BOOL. Does not mean it is the same....
You're right, they aren't the same but, there is one thing that is _always_ the same: not zero always means "true".  It's difficult to consider that "undefined behavior" when it is always the same. 

"undefined behavior" implies not predictable.


the way it's documented is incorrect. 
Different issue.
Not really.  It's documented according to what boolean is _supposed_ to be in Pascal which is different than what boolean actually is in FPC and Delphi.


But nothing in the field of boolean algebra somehow mandates that the representation has to be that way. Inventing a different representation would not be wrong, in the sense that it breaks something that is mandated by the underlying concept.
BUT, boolean algebra mandates only two possible values.  true = any non zero value violates that.

Choosing which gate state represents true or false is arbitrary but, a gate can represent only two values, zero and one (or whatever names you want to assign to them.)  It cannot represent zero and multiple distinct non zero values (they'll have to either, come up with 18 wheeler gates or, "elastic" gates, to accommodate FPC and Delphi's "boolean"s.)


Where does your application "shows that FPC (and Delphi) treat boolean the same as ByteBool, i.e, any non-zero value is true" ?
Fine... no problem.  Here is a little test program:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2.  
  3. program TestBoolean8Typecast;
  4. var
  5.   i : byte;
  6.  
  7.   b : boolean;
  8.  
  9. begin
  10.   for i := low(i) to high(i) do
  11.   begin
  12.     b := boolean(i);
  13.  
  14.     writeln('arithmetic b = ', ord(b):3, ' ', ' logical b = ', b);
  15.   end;
  16. end.
  17.  
It prints "true" 255 times and "FALSE" one time.  It's surprisingly consistent for something that is supposed to be "undefined behavior".   

In fact look at my "bitpacked" example. And assigning "x.a := boolean(2)", will lead to the writeln returning switching between printing true or false. So clearly undefined behaviour.
It's no surprise it trips all over itself when it tries to pack a value greater than 1 into 1 bit.  The code you posted shouldn't compile.   Even in the 21st century putting a value greater than 1 into a single bit, takes a David Copperfield act.

FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12177
  • Debugger - SynEdit - and more
    • wiki
Re: strange FPC error message
« Reply #20 on: June 08, 2020, 06:40:30 pm »
FPC is very consistent in considering "not zero" as true and "zero" as false.  That seems to be rather well defined. 
So now it all comes down to "consistent" or "repeatable"

However: "undefined" does not conflict with "consistent" or "repeatable"

If behaviour is defined, then (unless there is documented incompatibility) that behaviour should be the same in future versions.
I give you that the fact that at least on intel compatible (and most other cpu) the underlying test will always be for zero flag, this behaviour is likely to stay forever.
But
  likely <> guaranteed/documented

Undefined does not mean that it has to go different at some point. It only means that it could.
In other words, if FPC would change implementation, and results would change in future, then that would not be a incompatibility change. (Maybe there will be a CPU, where testing for 1 is easier that testing for 0 / Probably not, but if there was....)

In terms of programming languages, "defined" is when it is "documented".

So showing something to be repeatable, or to be consistent does not make it defined.


And you may try the below.  (Yes its a comparison....)
It prints
False
True

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. var a: boolean;
  3. begin
  4.   a:=boolean(5);
  5.   {$b+}
  6.   writeln(a=true);
  7.   {$b-}
  8.   writeln(a=true);
  9.   readln;
  10. end.
  11.  

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12177
  • Debugger - SynEdit - and more
    • wiki
Re: strange FPC error message
« Reply #21 on: June 08, 2020, 06:54:20 pm »
FPC and Delphi, treat boolean types inconsistently.  It they were consistent then it would not be possible for two boolean variables to both be true yet not equal to one another. 
FPC treats boolean always as enum (false=0, true=1)
FPC always treats it, as this are the only 2 binary representations that it can have.

IF the user forces another invalid value, then FPC does not detect that, and the outcome is not defined. (Also, due to implementation detail: consistent)

writeln(a)
- Will test for 1 of the 2 possible values. Due to how CPUs work, it will test for 0. But that is not documented, therefore not defined behaviour. It is implementation detail.
- If a is not 0, then it must be 1. So it is True.
- The possibility that a was neither 0 nor 1 is not considered at all.

If a = b then
- there are only 4 cases possible 0=0  0=1  1=0  1=1  => comparing the ordinal values will work for all of those cases.

The treatment is the same.

The observed outcome is due to implementation detail. And that is not the same as documented.


ASBzone

  • Hero Member
  • *****
  • Posts: 733
  • Automation leads to relaxation...
    • Free Console Utilities for Windows (and a few for Linux) from BrainWaveCC
Re: strange FPC error message
« Reply #22 on: June 08, 2020, 10:01:05 pm »
So now it all comes down to "consistent" or "repeatable"

However: "undefined" does not conflict with "consistent" or "repeatable"

I was going to comment on this very point.  The consistency of the undefined behavior doesn't make it any less undefined (or more defined).  It is just as likely to change in some future version, and no one would have right to complain about it, because the previous behavior was "undefined".

To 440bx's point, though, it might be worth some consideration to have the compiler generate a warning for weird typecasts.  I sort of see his point about that, but I personally wouldn't want it to be an error (although I'm not in the habit of abusing typecasts in this manner).
-ASB: https://www.BrainWaveCC.com/

Lazarus v4.3.0.0 (bcf314a670) / FreePascal v3.2.3-46-g77716a79dc (aka fixes)
(Windows 64-bit install w/Win32 and Linux on ARM and x64 cross-compilers via FpcUpDeluxe)

My Systems: Windows 10/11 Pro x64 (Current)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12177
  • Debugger - SynEdit - and more
    • wiki
Re: strange FPC error message
« Reply #23 on: June 08, 2020, 11:00:32 pm »
To 440bx's point, though, it might be worth some consideration to have the compiler generate a warning for weird typecasts.  I sort of see his point about that, but I personally wouldn't want it to be an error (although I'm not in the habit of abusing typecasts in this manner).

Well, a warning or even note/hint is problematic.
There are probably to many TWeekday(999). And for the compiler that is the same as Boolean(99). Even when it comes to bitpacking, and cut off.

Though there may be something, when it comes to cut off, due to the size of the target.
Especially with enums, that are usually oversized, unless bitpacked.
If you cast pointers to ordinals, you do get a warning. So maybe if you cast something to an enum, you should get a hint/warning, if it can/does lead to data loss. (hint if it could / warning if it actually does)


Another idea that came to my mind, directly targeted at boolean (the enum based, not the longbool), is a run time rangechecking if the value is used in an expression (without typecast). IE give a runtime error, if an out of range value would cause undefined behaviour in a condition.
I.e. you can still do
  bFoo := boolean(5);
  bBar := bFoo;
  if integer(bFoo) <> 0 then
but you cannot do (runtime range check error)
  bSome := bFoo and bBar; // boolean arithmetic
  if bFoo then // condition

I do guess however there are not enough people using that kind of boolean storage. So may not be worth the manhours.

440bx

  • Hero Member
  • *****
  • Posts: 6130
Re: strange FPC error message
« Reply #24 on: June 08, 2020, 11:43:32 pm »
I give you that the fact that at least on intel compatible (and most other cpu) the underlying test will always be for zero flag, this behaviour is likely to stay forever.
But
  likely <> guaranteed/documented
Yes, it's quite likely to stay forever because if that "undefined behavior" changed it would rather likely break a fair amount of existing code.

In terms of programming languages, "defined" is when it is "documented".
That is not a very solid foundation for any argument.  Documentation isn't always right.  Case in point, Boolean16 occupying 3 bytes.

So showing something to be repeatable, or to be consistent does not make it defined.
You want to play semantics ?... no problem.  whether defined or not, when some behavior is consistently repeatable, programmers sooner or later start depending on it.


IF the user forces another invalid value, then FPC does not detect that, and the outcome is not defined.
if FPC cannot "detect" that an out an of range, i.e, invalid, value is being used in "boolean(5)" then it really needs its "detection" abilities to be improved.  Mr. Magoo could probably "detect" that one.

The real problem is: Delphi has the same "detection" abilities.  That leaves FPC with little choice but to follow the blind with the one-eyed flat footed seeing dog.

FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12177
  • Debugger - SynEdit - and more
    • wiki
Re: strange FPC error message
« Reply #25 on: June 09, 2020, 12:21:30 am »
In terms of programming languages, "defined" is when it is "documented".
That is not a very solid foundation for any argument.  Documentation isn't always right.  Case in point, Boolean16 occupying 3 bytes.
I did not say, that documentation is always right. Nor that it is always complete.

You can file a bug, that Boolean16 is not 3 bytes. Or you can file a bug that the docs have a mistake. Either way, I can tell you, it will lead to the doc being fixed.

Quote
whether defined or not, when some behavior is consistently repeatable, programmers sooner or later start depending on it.
Whats your point?

The message that "the fpc compiler is consistent" stands.
The discussion was about the compiler, not about people
Again: what is the point of mentioning this?

Quote
IF the user forces another invalid value, then FPC does not detect that, and the outcome is not defined.
if FPC cannot "detect" that an out an of range, i.e, invalid, value is being used in "boolean(5)" then it really needs its "detection" abilities to be improved.  Mr. Magoo could probably "detect" that one.

"cannot" vs "does not"....

But why should it detect it?

Detecting it, would only be a valid issue, if the out of range value was valid to start with.
Detecting it could be an option for debugging (see my range checking comment).

Otherwise, It seems (i.e. "my guess", as I have no documentation on this)  to me, that it was a fully intentional decision that this should not be detected.
In any case, if it was detected, we did not need 2 distinct bool types for byte, word and bigger sizes. I.e. longbool would no longer differ from boolean32.

Having a type (boolean) that does not include that a check (as it is not meant to be used with such data) allows the compiler to optimize the expression.
If you need that functionality, use a type that supports it.

Anyway that was already discussed. And that leads away from the consistency question


Kays

  • Hero Member
  • *****
  • Posts: 632
  • Whasup!?
    • KaiBurghardt.de
Re: strange FPC error message
« Reply #26 on: June 09, 2020, 02:00:44 am »
Note, if you’re so concerned about your Boolean’s values, you can always write
Code: Pascal  [Select][+][-]
  1. b := Boolean() = true; // or, better:
  2. b := Boolean() <> false;
(only applicable for non-constant expressions, no lazy evaluation enabled [{$boolEval on}]).


[…]
Boolean is enum(False,True).
yes, it is and, it would nice if the compiler knew that too.  :D […]
For reference, false and true are defined via compiler/psystem.pas as part of the system unit.



[…] Since, per definition, they have to maintain the relations:
Ord(False) < Ord(True)
Succ(False) = True ==> Pred(True) = False


Or am I wrong?
For reference, see ISO 7185 (cf. letter c “Boolean-type”).



[…] file a bug, that Boolean16 is not 3 bytes. […]
I did that over one and a half years ago.
Yours Sincerely
Kai Burghardt

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12706
  • FPC developer.
Re: strange FPC error message
« Reply #27 on: June 09, 2020, 11:22:25 am »
[…] file a bug, that Boolean16 is not 3 bytes. […]
I did that over one and a half years ago.

And that fix is in the various documentation snapshots and 3.2.0 docs.

The snapshots are old, there was a rebuild for 3.2.0 in june with some late may fixes, but building is still ongoing and FTP is closed.

valdir.marcos

  • Hero Member
  • *****
  • Posts: 1151
Re: strange FPC error message
« Reply #28 on: June 09, 2020, 01:45:02 pm »
[…] file a bug, that Boolean16 is not 3 bytes. […]
I did that over one and a half years ago.

And that fix is in the various documentation snapshots and 3.2.0 docs.

The snapshots are old, there was a rebuild for 3.2.0 in june with some late may fixes, but building is still ongoing and FTP is closed.
Thanks.

 

TinyPortal © 2005-2018