This forum is deprecated.
There is an interesting discussion going on in the FreePascal forum regarding how untyped unsigned literals are not used correctly with typed variables and expressions without needing explicit type-casts:
Implicit converison, literals and QWORD variable warning
(apparently the original thread has been locked, so I posted a reply in a new thread linking to this post here)
Some posts are suggesting this is handled differently between Delphi and FreePascal (regardless of whether Delphi mode is used or not) and are asking for confirmation about the behavior in the latest Delphi. I don't have Rio or Sydney installed, so I can't answer this.
Here are some examples provided in that discussion that are causing issues in FreePascal. How does Delphi handle them nowadays? FYI, QWORD = UInt64.
// qw:= $FFFFFFFFFFFFFFFF; // By compiler it is -1 and it shows range check warning, literals are treated as int64?
qw:= QWORD($FFFFFFFFFFFFFFFF); // This will pass with exact cast, no warning
if qw < 0 then // Warning: Comparison might be always false due to range of constant and expression
Writeln('QWORD variable s less than 0!?!'); // Warning: unreachable code
if word($FFFFFFFFFFFFFFFF) < 0 then
Writeln('Cast unsigned QWORD is less than 0!?!'); // Warning: unreachable code
if $FFFFFFFFFFFFFFFF < 0 then
Writeln('Uncast literal $FFFFFFFFFFFFFFFF is treated as -1 !'); // It is always executed
// doesn't work
c64: array [0..1] of QWord =
c64: array [0..1] of QWord =
if $FFFFFFFFFFFFFFFF < 0 then // This should'n give warning on Rio
Writeln('Uncast literal $FFFFFFFFFFFFFFFF is treated as -1 !'); // It should never be executed on Rio
RAD STUDIO 10.3.3 ARCH (7899) and RAD SUDIO 10.4 Sydney Arch (9797) (with Patches 1, 2 and 3)
Delphi: Defines a 64-bit unsigned integer type.
UInt64 represents a subset of the natural numbers. The range for the UInt64 type is from 0 through 2^64-1.
The size of UInt64 is 64 bits across all 64-bit and 32-bit platforms.
Now comes a question from me:
IntToStr() does not have an overload for UInt64, only for Integer and Int64, so you are invoking an implicit conversion from UInt64 to Int64. $FFFFFFFFFFFFFFFF in UInt64 has all its bits set to 1. -1 in Int64 also has all of its bits set to 1.
To convert a UInt64 to a String without losing any precision, you can use Format('%u') or TUInt64Helper.ToString().
But it is past time for Embarcadero to update the function system, since it is already a fact that we are in the 64bit era.
For the more fortunate, this era (64bits) also doesn't make much sense, especially in "cosmic" mathematics.
Naturally, we are communicating in conventional procedures with binaries in full use!I'll give you a discount!
I think the whole problem of conversions is in this 2 arbitrary (and related) function, using the max values for Integer and Int64
System.SysUtils.pasline: 8248, function _IntToStr32(Value: Cardinal; Negative: Boolean): string;line: 8289 function _IntToStr64(Value: UInt64; Negative: Boolean): string;