View Issue Details

IDProjectCategoryView StatusLast Update
0034058FPCCompilerpublic2018-10-17 21:48
ReporterThaddy de Koning Assigned ToSven Barth  
PrioritynormalSeverityminorReproducibilityalways
Status assignedResolutionreopened 
PlatformallOSall 
Product Version3.1.1 
Fixed in Version3.3.1 
Summary0034058: Boolean8 revistited
DescriptionBoolean8 is defined tn the compiler sources but it lacks the implementation.

I think this is an omission rather that the fix in the documentation as per the related bug report 0034052 (which is closed to me so I could not request for comment)
Steps To Reproduceif I look at symdef.pas and psystem.pas it is indeed not registered to the compiler, although the underlying pasbool8type IS defined. The rest are all registered to the compiler.
It is also not defined for the debugger.

I think this is an omission rather than documentation. The two are distinctly different. And the suggested work-around is also distinctly different.

Additional InformationI can provide a patch for that if you want. Otherwise the documentation fix is OK with me.
TagsNo tags attached.
Fixed in Revision39673
FPCOldBugId
FPCTarget
Attached Files

Relationships

related to 0034052 resolvedMichael Van Canneyt Boolean8 is not recognized as a built in datatype 

Activities

J. Gareth Moreton

2018-07-30 16:10

developer   ~0109766

I'm a bit confused as to why "boolean8" is being referenced at all. It's always been "ByteBool" for Object Pascal.

Thaddy de Koning

2018-07-30 17:49

reporter   ~0109768

I am too, but it can simply be an alias.
Thing is it partly exists: the compiler code has *some* reference to it, the documentation as well, but subsequently it has no further implementation.
I am fine with it either way.
Simplest fix is remove pasbool8type from the compiler sources and do the docs as Michael already did.

Thaddy de Koning

2018-07-31 11:03

reporter   ~0109777

On second thought it may hurt 8 bit platforms a bit. (which FPC supports)

Marco van de Voort

2018-07-31 13:39

manager   ~0109781

bytebool is a C boolean type (0=false, rest = true). Boolean8 is equal to normal pascal boolean (0=false 1=true, rest undefined)

Sven Barth

2018-08-03 15:39

manager   ~0109857

Boolean8 = Boolean (not ByteBool) and that's exactly what pasbool8type is used for.

Thaddy de Koning

2018-08-05 07:47

reporter   ~0109889

Last edited: 2018-08-05 07:51

View 2 revisions

I still feel that its purpose is different. Although the underlying Boolean has the same layout and resolution 0..1 it is in fact distinct in its purpose and should be declared as a distinct type
I would request to include it after all as:

type
  Boolean8 = type Boolean; // typed type: that is not an alias.

This reflects its purpose better. It is also non-breaking and easy to implement.
After all there are more languages than C to interface with and even some C's are not always true is any value but zero.
I feel strongly that this is a better solution, but if you do not agree plz re-close. I am not prepared to go to war over it <grin>.

440bx

2018-08-05 18:33

reporter   ~0109897

It might help to be precise about what the real difference between the various Boolean types is.

A Boolean, Boolean16, Boolean32 and Boolean64 are set to the value 1 whenever they are set to "true". i.e, booleanxx := true; generates mov size ptr [var_name], 1

whereas,

a bytebool, wordbool, longbool and qwordbool are set to -1 whenever they are set to "true". e.e sizebool := true; generates move size ptr [var_name], 0xFF (as many Fs as need to fill the type).

Logically there is no difference whatsoever between the types, a non zero value is considered true, a zero value, false.

The nonsense of chosing a value of -1 to mean true started with Delphi2 (if memory serves) and it was specifically to make Delphi compatible with Visual Basic of all things.

Simply document that the byte/word/long/qword bools get their value set to -1 when set to true and the Booleans used by most homo sapiens are set to 1 when their value is set to true.

J. Gareth Moreton

2018-08-05 20:33

developer   ~0109898

Setting a value to -1 to indicate "True" does have some sense, as it means "Not BoolValue" will always invert its state (from all 1s to all 0s and vice versa) no matter the size of the Boolean type. Still, if the documentation can be cleared up, then we can wrap this one up.

Marģers

2018-08-06 12:54

reporter   ~0109902

type boolean has slightly different behavior from other boolean types.
In example below, if replace type boolean with any other boolean type, then output will give only "true". At this point it's wrong to make alias boolean8 = boolean;

var b1, b2, b3 : boolean;
    z : bytebool;
begin
     b1:=boolean(1);
     b2:=boolean(2);
     b3:=boolean(2);
     z := bytebool(2);
     writeln(b1,' ',b2,' ',b3,' ',z); // TRUE TRUE TRUE TRUE
     if b1 = b2 then writeln ('true') else writeln ('false'); // false
     if b2 = b3 then writeln ('true') else writeln ('false'); // true
     if b1 = z then writeln ('true') else writeln ('false'); // true
     if b2 = z then writeln ('true') else writeln ('false'); // false
end.

Thaddy de Koning

2018-08-06 13:41

reporter   ~0109904

Delphi 7 has boolean (true) as -1, not one.

Thaddy de Koning

2018-08-06 13:48

reporter   ~0109905

"a bytebool, wordbool, longbool and qwordbool are set to -1".
???? So unsigned types can be -1? That's not a very helpful comment.

On a more serious side: delphi 7 returns -1 for Boolean, which indicates it is a signed type.
That does not matter for the discussion. See my re-open comment.

440bx

2018-08-06 20:36

reporter   ~0109920

The inclusion of a boolean8 would only be for symmetry. The behavior of Boolean types is already cast and cannot change without breaking a lot of code.

One of the things that programmers should be aware of is that the Boolean properties are not transitive as implemented. Here is an example, when two independent TRUE conditions lead to a different result (they should not.)

{$MODE OBJFPC }

// FPC is treating logical types just as C does. They are not really logical
// types, just integers that are logically interpreted as being true for a
// non zero value and false otherwise. That's not a true logical type, it's a
// C_ism.

program BooleanTest2;

function TestBoolean() : boolean;
var
  b8 : boolean;
  b16 : boolean16;

begin
  ord(b8) := 3; // true
  ord(b16) := 7; // true

  writeln('b8 = ', b8); // outputs TRUE
  writeln('b16 = ', b16); // outputs TRUE too

  if boolean(b8) = boolean(b16) then // same result without the typecast
  begin
    writeln('b8 equal b16');
  end
  else
  begin
    writeln('b8 NOT equal b16');// TRUE <> TRUE ??? - no transitivity.
  end;


  b8 := boolean(3); // true - should convert it to 1
  b16 := boolean(7); // true - same here (range check complaint though)

  writeln('b8 = ', b8); // outputs TRUE
  writeln('b16 = ', b16); // outputs TRUE too

  if boolean(b8) = boolean(b16) then // same result without the typecast
  begin
    writeln('b8 equal b16');
  end
  else
  begin
    writeln('b8 NOT equal b16'); // same as above. Not transitive.
  end;


  result := true;
end;

begin
  TestBoolean();
end.

Marģers

2018-08-06 21:53

reporter   ~0109921

At this point boolean is compatible with Turbo Pascal.
Boolean special feature appears only if type casted. If want type cast better use bytebool instead, and then it will act like true if any bit set to 1.

> b8 := boolean(3); // true - should convert it to 1
Not agree with that. There is case where it's not so clear.

b8:= boolean($300); // FALSE - it should or should not converted to 1
and there is also records with case of syntax, it could make a mess.

I guess, better introduce boolean8 similar to boolean16.

440bx

2018-08-06 23:39

reporter   ~0109922

I just wanted to point out the problem. Booleans in FPC work the way they do in Delphi and considering the goal to be Delphi compatible, in that regard, it makes sense.

That said, in the case of b8 := Boolean(3), it most definitely should convert it to 1. One of the many reasons it should do that is because, a non bitpacked Boolean now behaves differently than a bitpacked Boolean. The bitpacked Boolean obviously cannot host a value of 3, it can only host 0 or 1.

Allowing Booleans to behave like integers results in ambiguities. One of them shown in the example I provided. Transitivity is gone because instead of comparing the logical value what is being compared are the ordinal values with the special case that 0 means false.

in both examples, b8 : ($300) and b8 := 3, the proper course of action is for the compiler to reject the assignment as it is clearly not within the range of a Boolean (0..1). Accepting that is what leads to all the ambiguities.

It would be nice if the BooleanXX types behaved like TRUE Booleans and the "size"bool (e.g, bytebool) behaved like the C wannabe Boolean type.

I don't expect that to happen since a change like that could break quite a bit of code out there.

Marģers

2018-08-07 07:04

reporter   ~0109924

Last edited: 2018-08-09 09:33

View 2 revisions

Type "boolean" isn't real life problem and it behaves according documentation.

Serge Anvarov

2018-08-07 19:11

reporter   ~0109931

>> b8 := boolean(3); // true - should convert it to 1
>Not agree with that. There is case where it's not so clear.
I think it's must. And now it is already an error, because the following correct code calls SIGSEGV

{$APPTYPE CONSOLE}
uses SysUtils;

function Test(const B: Boolean): string;
const
  C: array[Boolean] of string = ('False', 'True');
begin
  Result := C[B];
end;

var
  B: Boolean = Boolean(2);
begin
  Writeln(Test(B));
  Readln;
end.

Although this error is compatible with Delphi. :)

440bx

2018-08-07 19:39

reporter   ~0109933

Nice example Serge.

Marģers

2018-08-07 21:57

reporter   ~0109936

Last edited: 2018-08-07 22:04

View 2 revisions

@Serge Anvarov, add {$r+} directive and you won't be able even compile program. Boolean has strict range 0..1
Boolean(2); doesn't work - gives out of range error.

In first place I gave example how boolean differs from other boolean types, but not because there are bug or something. It's reason to implement type boolean8 and not make simple alias to boolean.

440bx

2018-08-07 22:11

reporter   ~0109937

@margers: the $r+ is for the compiler to generate run time range checking code. In an assignment such as "B:Boolean = Boolean(2)" no run time checking is necessary. The range violation is right there and exists at compile time. The compiler should NOT allow that (at least not for a true Boolean type.)

That $r+ would affect allowed ranges during compile time is already very questionable. It shouldn't. It's supposed to control range checking code generation, not what ranges are acceptable for a data type at compilation time.

Marģers

2018-08-07 23:07

reporter   ~0109938

indeed, if {$r+} there are no (or failing) range checking for line: Result := C[B];


Actually {$r+} affect allowed ranges during compile time. For me it's also surprise.

Serge Anvarov

2018-08-08 19:44

reporter   ~0109949

>...add {$r+} directive and you won't be able even compile program
OK. This work:
{$APPTYPE CONSOLE}
{$RANGECHECKS ON}

function Test(const B: Boolean): string;
const
  C: array[Boolean] of string = ('False', 'True');
  OutOfRange: string = 'Out of range';
begin
  if OutOfRange <> '' then // Force compiler include unused const
    Result := C[B];
end;

var
  B: Boolean;
begin
  B := Boolean(2);
  Writeln(Test(B));
  Readln;
end.

Marģers

2018-08-09 09:41

reporter   ~0109954

> {$r+} affect allowed ranges during compile time.

it's true only for typed constant evaluation
example
const b : boolean = boolean(2);
var z : boolean = boolean(2);

Sven Barth

2018-08-24 17:54

manager   ~0110291

I've added an alias from Boolean8 to Boolean for the sake of symmetry. That's all I'm going to concede here.

Thaddy de Koning

2018-10-17 21:48

reporter   ~0111444

Alas, even after the fix by Jonas I can still reproduce some -1 failures in external C code. I thought it worked. Feel free to read the deleted post.

Issue History

Date Modified Username Field Change
2018-07-30 14:31 Thaddy de Koning New Issue
2018-07-30 16:09 J. Gareth Moreton Relationship added related to 0034052
2018-07-30 16:10 J. Gareth Moreton Note Added: 0109766
2018-07-30 17:49 Thaddy de Koning Note Added: 0109768
2018-07-31 11:03 Thaddy de Koning Note Added: 0109777
2018-07-31 13:39 Marco van de Voort Note Added: 0109781
2018-08-03 15:39 Sven Barth Note Added: 0109857
2018-08-03 15:39 Sven Barth Status new => resolved
2018-08-03 15:39 Sven Barth Resolution open => no change required
2018-08-03 15:39 Sven Barth Assigned To => Sven Barth
2018-08-05 07:47 Thaddy de Koning Note Added: 0109889
2018-08-05 07:47 Thaddy de Koning Status resolved => feedback
2018-08-05 07:47 Thaddy de Koning Resolution no change required => reopened
2018-08-05 07:51 Thaddy de Koning Note Edited: 0109889 View Revisions
2018-08-05 18:33 440bx Note Added: 0109897
2018-08-05 20:33 J. Gareth Moreton Note Added: 0109898
2018-08-06 12:54 Marģers Note Added: 0109902
2018-08-06 13:41 Thaddy de Koning Note Added: 0109904
2018-08-06 13:41 Thaddy de Koning Status feedback => assigned
2018-08-06 13:48 Thaddy de Koning Note Added: 0109905
2018-08-06 20:36 440bx Note Added: 0109920
2018-08-06 21:53 Marģers Note Added: 0109921
2018-08-06 23:39 440bx Note Added: 0109922
2018-08-07 07:04 Marģers Note Added: 0109924
2018-08-07 19:11 Serge Anvarov Note Added: 0109931
2018-08-07 19:39 440bx Note Added: 0109933
2018-08-07 21:57 Marģers Note Added: 0109936
2018-08-07 22:04 Marģers Note Edited: 0109936 View Revisions
2018-08-07 22:11 440bx Note Added: 0109937
2018-08-07 23:07 Marģers Note Added: 0109938
2018-08-08 19:44 Serge Anvarov Note Added: 0109949
2018-08-09 09:33 Marģers Note Edited: 0109924 View Revisions
2018-08-09 09:41 Marģers Note Added: 0109954
2018-08-24 17:54 Sven Barth Fixed in Revision => 39673
2018-08-24 17:54 Sven Barth Note Added: 0110291
2018-08-24 17:54 Sven Barth Status assigned => resolved
2018-08-24 17:54 Sven Barth Fixed in Version => 3.3.1
2018-08-24 17:54 Sven Barth Resolution reopened => fixed
2018-10-17 21:36 Thaddy de Koning Status resolved => feedback
2018-10-17 21:36 Thaddy de Koning Resolution fixed => reopened
2018-10-17 21:48 Thaddy de Koning Note Added: 0111444
2018-10-17 21:48 Thaddy de Koning Status feedback => assigned