Recent

Author Topic: Any traces of «if» statement disappeared  (Read 2077 times)

PascalDragon

  • Hero Member
  • *****
  • Posts: 952
  • Compiler Developer
Re: Any traces of «if» statement disappeared
« Reply #15 on: January 21, 2020, 02:51:22 pm »
In 3.0.2 64, QWORD is a intrinsic type and Uint64 = QWORD

I am sure it's the same for the 32 bit verison/.
That looks correct to me.

Code: [Select]
0 1>markMLl@desktop:~$ cat test.pas
program test;

var
  x, y, z: qword;

begin
  x := $7fffffffffffffff;
  y := $ffffffffffffffff;
  z := $8000000000000000
end.

0 1>markMLl@desktop:~$ fpc test
Free Pascal Compiler version 3.0.4 [2018/07/03] for x86_64
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling test.pas
test.pas(8,8) Warning: range check error while evaluating constants (-1 must be between 0 and 18446744073709551615)
test.pas(9,8) Warning: range check error while evaluating constants (-9223372036854775808 must be between 0 and 18446744073709551615)
test.pas(4,3) Note: Local variable "x" is assigned but never used
test.pas(4,6) Note: Local variable "y" is assigned but never used
test.pas(4,9) Note: Local variable "z" is assigned but never used
Linking test
/usr/bin/ld: warning: link.res contains output sections; did you forget -T?
11 lines compiled, 0.1 sec
2 warning(s) issued
3 note(s) issued

Note warnings in line 8 & 9.
As I have written above 64-bit constants are always signed. In Pascal the result of an expression also does not depend on what it is assigned to (with a few exceptions like overloaded function/method pointers). And Pascal has signed as the main type. Thus you need to explicitly cast the constant to QWord. This does in no way mean that QWord is signed.

Avinash

  • New Member
  • *
  • Posts: 25
Re: Any traces of «if» statement disappeared
« Reply #16 on: January 23, 2020, 08:41:17 pm »
Where if F.Handle <> invalid_Handle_Value then / else ?

It was the tip of the iceberg. In old Pascal programs LongInt is widely used in comparing file signatures, identifiers, and also in bit fields. Four ASCII characters can easily be more than $7FFFFFFF.
In {$MODE TP} the Integer becomes SmallInt, but the functioning of LongInt remains unchanged, while in Turbo Pascal it is different. Similar to how Int64 works now:

Code: Pascal  [Select]
  1. var
  2.   L: LongInt;
  3.   I: Int64;
  4. begin
  5.   L := $FFFFFFFF;
  6.   WriteLn(L = $FFFFFFFF);           { = FALSE   (Turbo Pascal gives TRUE) }
  7.  
  8.   I := $FFFFFFFFFFFFFFFF;
  9.   WriteLn(I = $FFFFFFFFFFFFFFFF);   { = TRUE  }
  10. end.

As a result, only about half of the comparisons remain working when compiling this FPC. Need I say what will happen to the code if you cross out half the lines?
I tried to overload the comparison operator, but I got a message that this is «impossible»

Code: Pascal  [Select]
  1. operator = (D: DWord; L: LongInt) B: Boolean; Inline;
  2. begin
  3.   B := (D = DWord(L));
  4. end;

Is there a solution other than manually editing a iceberg of code?

PascalDragon

  • Hero Member
  • *****
  • Posts: 952
  • Compiler Developer
Re: Any traces of «if» statement disappeared
« Reply #17 on: January 24, 2020, 04:10:25 pm »
It was the tip of the iceberg. In old Pascal programs LongInt is widely used in comparing file signatures, identifiers, and also in bit fields. Four ASCII characters can easily be more than $7FFFFFFF.
In {$MODE TP} the Integer becomes SmallInt, but the functioning of LongInt remains unchanged, while in Turbo Pascal it is different.

Integer is defined as a type that changes its meaning with the mode (TP, FPC vs. ObjFPC, Delphi) while LongInt is always 32-bit.

Similar to how Int64 works now:

Code: Pascal  [Select]
  1. var
  2.   L: LongInt;
  3.   I: Int64;
  4. begin
  5.   L := $FFFFFFFF;
  6.   WriteLn(L = $FFFFFFFF);           { = FALSE   (Turbo Pascal gives TRUE) }
  7.  
  8.   I := $FFFFFFFFFFFFFFFF;
  9.   WriteLn(I = $FFFFFFFFFFFFFFFF);   { = TRUE  }
  10. end.

As a result, only about half of the comparisons remain working when compiling this FPC. Need I say what will happen to the code if you cross out half the lines?

Please pay attention to the warnings that FPC generates. When I compile that code I get the following output:

Code: [Select]
Compiling .\fpctests\ttest.pp
ttest.pp(7,8) Warning: Range check error while evaluating constants (4294967295 must be between -2147483648 and 2147483647)
ttest.pp(8,13) Warning: Comparison might be always false due to range of constant and expression
Linking testoutput\ttest.exe
12 lines compiled, 0.0 sec, 28512 bytes code, 1300 bytes data
2 warning(s) issued

The first warning explicitly tells you why that comparison is wrong. FPC supports 64-bit values, this is why $FFFFFFFF is interpreted as signed 64-bit value. And that is not equal to LongInt($FFFFFFFF).

You can compile with -Sew so that all warnings are handled as errors. Please note that this really means all warnings. Using {$warn XXX error} (where XXX is the error number you can get when compiling with -vq) you can also selectively treat some warnings as errors. My suggestion would be to put these into an include file and to include that at the top of all of your units.

I tried to overload the comparison operator, but I got a message that this is «impossible»

Code: Pascal  [Select]
  1. operator = (D: DWord; L: LongInt) B: Boolean; Inline;
  2. begin
  3.   B := (D = DWord(L));
  4. end;

Only operators that don't have an internal operator can be overloaded.

ASerge

  • Hero Member
  • *****
  • Posts: 1442
Re: Any traces of «if» statement disappeared
« Reply #18 on: January 24, 2020, 04:37:59 pm »
Code: Pascal  [Select]
  1. var
  2.   L: LongInt;
  3.   I: Int64;
  4. begin
  5.   L := $FFFFFFFF;
  6.   WriteLn(L = $FFFFFFFF);           { = FALSE   (Turbo Pascal gives TRUE) }
  7.  
  8.   I := $FFFFFFFFFFFFFFFF;
  9.   WriteLn(I = $FFFFFFFFFFFFFFFF);   { = TRUE  }
  10. end.
By the way in Delphi False not only in the first case, but also in the second. Delphi believes that the signed Int64 can never be equal to the maximum unsigned.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7919
Re: Any traces of «if» statement disappeared
« Reply #19 on: January 24, 2020, 04:39:52 pm »
It was the tip of the iceberg. In old Pascal programs LongInt is widely used in comparing file signatures, identifiers, and also in bit fields. Four ASCII characters can easily be more than $7FFFFFFF.

Yes, probably.

Is there a solution other than manually editing a iceberg of code?

No, hackish solutions like the overload are not wise since not very transparent. You never know if they fix everything adequately in all cases, and worse they can mask warnings.

Delphi 4 is from 1998, so this change is already 22 years old. (though to be fair, FPC only has it since 1.9.x precursor series in late 2003). Time to kill the beast.



lucamar

  • Hero Member
  • *****
  • Posts: 2364
Re: Any traces of «if» statement disappeared
« Reply #20 on: January 24, 2020, 05:02:19 pm »
Four ASCII characters can easily be more than $7FFFFFFF.

Yes, probably.

If we're really talking of ASCII characters then no, it can never be: ASCII only defines characters $00..$7F. Unless one defines ASCII as "not quite just ASCII".

Yes, I know: "nitpicking" ... but let's use correct terminology ;)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.4/2.0.6  - FPC 3.0.4 on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Avinash

  • New Member
  • *
  • Posts: 25
Re: Any traces of «if» statement disappeared
« Reply #21 on: January 26, 2020, 05:11:33 pm »
Using {$warn XXX error} (where XXX is the error number you can get when compiling with -vq) you can also selectively treat some warnings as errors. My suggestion would be to put these into an include file and to include that at the top of all of your units.

Thanks, very good advice. I fixed a lot of undetected bugs in this way (also those with asm reg32, Word). This message filtering is very useful since the original 500 warnings were untreatable, even with redirection to the file using -Fe.

I note that something doesn’t work in FPC with directive parsing, and outside of simple pieces, the $WARN directive works with message numbers is somehow inconsistently, or maybe some of the directives are skipped (and with +/- instead of ON/OFF it doesn't seem to parse at all). Using the -vm keys here is a much more reliable way (if I remember correctly, I had the same problem with $ASMMODE, and I was forced to use the -Rintel switch instead of the directive).

PascalDragon

  • Hero Member
  • *****
  • Posts: 952
  • Compiler Developer
Re: Any traces of «if» statement disappeared
« Reply #22 on: January 27, 2020, 09:22:25 am »
I note that something doesn’t work in FPC with directive parsing, and outside of simple pieces, the $WARN directive works with message numbers is somehow inconsistently, or maybe some of the directives are skipped (and with +/- instead of ON/OFF it doesn't seem to parse at all). Using the -vm keys here is a much more reliable way (if I remember correctly, I had the same problem with $ASMMODE, and I was forced to use the -Rintel switch instead of the directive).

According to the docs +/- should work for $WARN. Could either be a bug in the compiler or in the documentation. Can you provide a reproducible, self contained example?

Also you need to add these to each unit (that's why I said include file). Only adding them e.g. in the main program file will not work.

Thaddy

  • Hero Member
  • *****
  • Posts: 9597
Re: Any traces of «if» statement disappeared
« Reply #23 on: January 27, 2020, 09:26:42 am »
I can't reproduce it, e.g. {$warn 5026-} etc works. Maybe you used a space before - ? That indeed does not work.
[edit]
Not anymore, may be regression?
« Last Edit: January 27, 2020, 12:17:25 pm by Thaddy »
Mac died, can't really support it right now.

PascalDragon

  • Hero Member
  • *****
  • Posts: 952
  • Compiler Developer
Re: Any traces of «if» statement disappeared
« Reply #24 on: January 27, 2020, 09:32:06 am »
Then that would be a bug in the documentation that has a space there.

Avinash

  • New Member
  • *
  • Posts: 25
Re: Any traces of «if» statement disappeared
« Reply #25 on: January 27, 2020, 09:53:10 am »
I can't reproduce it, e.g. {$warn 5026-} etc works. Maybe you used a space before - ? That indeed does not work.

It does not work for me

Code: Pascal  [Select]
  1. {$WARN 5026-}
  2. begin
  3. end.

fpc test.pas

Code: Pascal  [Select]
  1. Target OS: Win32 for i386                                          
  2. Compiling test.pas                                                
  3. test.pas(1,2) Error: Illegal state "" for $WARN directive          
  4. test.pas(3,4) Fatal: There were 1 errors compiling module, stopping
  5. Fatal: Compilation aborted                                        
  6. Error: D:\FPC\bin\i386-Win32\ppc386.exe returned an error exitcode

fpc -n test.pas

Code: Pascal  [Select]
  1. test.pas(1,2) Error: Illegal state "" for $WARN directive        
  2. Fatal: Can't find unit system used by Program                    
  3. Fatal: Compilation aborted                                        
  4. Error: D:\FPC\bin\i386-Win32\ppc386.exe returned an error exitcode

Also you need to add these to each unit (that's why I said include file). Only adding them e.g. in the main program file will not work.

Yes, I did so, such a file exists. It is not included in absolutely all units, but part of the warnings did not turn off in the unit where it was included.

Thaddy

  • Hero Member
  • *****
  • Posts: 9597
Re: Any traces of «if» statement disappeared
« Reply #26 on: January 27, 2020, 10:22:21 am »
I believe it used to work, but a workaround is {$warn 5024 off}. It still works from the commandline, though: fpc -vw5024-
Mac died, can't really support it right now.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7919
Re: Any traces of «if» statement disappeared
« Reply #27 on: January 27, 2020, 10:39:17 am »
And please file a bug since this is a documentation discrepancy

Thaddy

  • Hero Member
  • *****
  • Posts: 9597
Re: Any traces of «if» statement disappeared
« Reply #28 on: January 27, 2020, 12:09:29 pm »
And please file a bug since this is a documentation discrepancy
Yes, but I think the underlying issue is the inconsistency in the parser, so what way should it be resolved?
Documenting away issues is something I do not really like....

I can submit one, but in what direction? Parser or Doc? Your opinion is valuable and appreciated.
« Last Edit: January 27, 2020, 12:15:09 pm by Thaddy »
Mac died, can't really support it right now.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7919
Re: Any traces of «if» statement disappeared
« Reply #29 on: January 27, 2020, 12:21:04 pm »
Put it in compiler bug to indicate that is your prefered fix, with a suggestion that if they won't at least the docs should be changed.