Try changing handle to unsigned, or maybe typecasting the result of the windows api FIND* functions if you want them to return deviant types.
Yes you are right. My dissatisfaction was caused by the fact that when I changed the type of TOSSearchRec.Handle to DWord, nothing changed, but this turned out to be because somewhere there was a type definition of DWord = LongInt. And so everything in FPC is correct.
This is incorrect. QWord is an unsigned type. However untyped 64-bit constants are always considered signed unless they are cast to QWord.Yes you are right. My dissatisfaction was caused by the fact that when I changed the type of TOSSearchRec.Handle to DWord, nothing changed, but this turned out to be because somewhere there was a type definition of DWord = LongInt. And so everything in FPC is correct.
Also note that QWord is defined as signed, so defining large unsigned 64-bit numbers needs a cast. Unfortunate... and in fairness I have to say that when I queried that a year or so ago it was described to me as a compiler design choice. So it's not entirely a library coding issue.
Also note that QWord is defined as signed, so defining large unsigned 64-bit numbers needs a cast. Unfortunate... and in fairness I have to say that when I queried that a year or so ago it was described to me as a compiler design choice. So it's not entirely a library coding issue.This is incorrect. QWord is an unsigned type. However untyped 64-bit constants are always considered signed unless they are cast to QWord.
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.
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
That is also not true. Where did you get that idea?Also note that QWord is defined as signed, so defining large unsigned 64-bit numbers needs a cast. Unfortunate... and in fairness I have to say that when I queried that a year or so ago it was described to me as a compiler design choice. So it's not entirely a library coding issue.This is incorrect. QWord is an unsigned type. However untyped 64-bit constants are always considered signed unless they are cast to QWord.
My apologies. I meant to say that QWord is implemented internally as a signed 64-bit.
That is also not true. Where did you get that idea?
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.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.
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:
var L: LongInt; I: Int64; begin L := $FFFFFFFF; WriteLn(L = $FFFFFFFF); { = FALSE (Turbo Pascal gives TRUE) } I := $FFFFFFFFFFFFFFFF; WriteLn(I = $FFFFFFFFFFFFFFFF); { = TRUE } 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?
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
I tried to overload the comparison operator, but I got a message that this is «impossible»
operator = (D: DWord; L: LongInt) B: Boolean; Inline; begin B := (D = DWord(L)); 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.
var L: LongInt; I: Int64; begin L := $FFFFFFFF; WriteLn(L = $FFFFFFFF); { = FALSE (Turbo Pascal gives TRUE) } I := $FFFFFFFFFFFFFFFF; WriteLn(I = $FFFFFFFFFFFFFFFF); { = TRUE } end.
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.
Is there a solution other than manually editing a iceberg of code?
Four ASCII characters can easily be more than $7FFFFFFF.
Yes, probably.
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 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).
I can't reproduce it, e.g. {$warn 5026-} etc works. Maybe you used a space before - ? That indeed does not work.
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.
And please file a bug since this is a documentation discrepancyYes, but I think the underlying issue is the inconsistency in the parser, so what way should it be resolved?