### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Implicit converison, literals and QWORD variable warning  (Read 2721 times)

#### julkas

• Guest
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #45 on: August 08, 2020, 09:52:59 am »
Thank you very much, julkas.

This is with Rio, I suppose. All seems to work as expected here.

His IntToStr() probably have no overloaded function for QWord/uint64. Can you add this code please (code is fixed in my previous post):

Code: Pascal  [Select][+][-]
1.       Writeln(qw);
2.       Writeln(\$FFFFFFFFFFFFFFFF);
3.
No problem. Code -
Code: Pascal  [Select][+][-]
1. program consta;
2. {\$IFDEF FPC}
3. {\$MODE Delphi}
4. {\$ENDIF}
5. uses SysUtils;
6. type
7. QWord = UInt64;
8.     var
9.       qw: QWord;
10.     begin
11.
12.       qw := \$FFFFFFFFFFFFFFFF;
13.       Writeln(qw);
14.       Writeln(\$FFFFFFFFFFFFFFFF);
15.
16.       Writeln(IntToStr(qw));
17.       Writeln(IntToStr(\$FFFFFFFFFFFFFFFF));
18.
19.       if qw < 0 then
20.         Writeln('Uncast unsigned QWORD is less than 0!?!');
21.
22.       if qword(\$FFFFFFFFFFFFFFFF) < 0 then
23.         Writeln('Cast unsigned QWORD is less than 0!?!');
24.
25.       if \$FFFFFFFFFFFFFFFF < 0 then
26.         Writeln('Uncast literal \$FFFFFFFFFFFFFFFF is treated as -1 !');
27.
28.     end.
29.
Output -
Code: Bash  [Select][+][-]
1. \$ dcc64 -B -NSSystem consta.pas
2. Embarcadero Delphi for Win64 compiler version 33.0
3. Copyright (c) 1983,2018 Embarcadero Technologies, Inc.
4. consta.pas(17) Warning: W1012 Constant expression violates subrange bounds
5. consta.pas(29)
6. 30 lines, 0.11 seconds, 175796 bytes code, 63312 bytes data.
7.
8. \$ ./consta.exe
9. 18446744073709551615
10. 18446744073709551615
11. -1
12. -1
13.

#### process_1

• Guest
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #46 on: August 08, 2020, 10:25:51 am »
Thank you julkas, once again!

Let see how FPC works in Delphi mode:

The code:
Code: Pascal  [Select][+][-]
1. program test;
2.
3. {\$IFDEF FPC}
4.   {\$MODE Delphi}
5. {\$ENDIF}
6.
7. uses
8.   SysUtils;
9.
10. {\$IFNDEF FPC}
11. type
12.   QWord = UInt64;
13. {\$ENDIF}
14.
15. var
16.   qw: QWord;
17. begin
18.
19.   qw := \$FFFFFFFFFFFFFFFF;
20.
21.   Writeln('Write variable and constant literal:');
22.   Writeln(qw);
23.   Writeln(\$FFFFFFFFFFFFFFFF);
24.   Writeln(18446744073709551615);
25.
26.   Writeln;
27.   Writeln('Write with IntToStr:');
28.   Writeln(IntToStr(qw));
29.   Writeln(IntToStr(\$FFFFFFFFFFFFFFFF));
30.   Writeln(IntToStr(18446744073709551615));
31.
32.   Writeln;
33.
34.   if qw < 0 then
35.     Writeln('Uncast unsigned QWORD is less than 0!?!');
36.
37.   if qword(\$FFFFFFFFFFFFFFFF) < 0 then
38.     Writeln('Cast unsigned QWORD is less than 0!?!');
39.
40.   if \$FFFFFFFFFFFFFFFF < 0 then
41.     Writeln('Uncast literal \$FFFFFFFFFFFFFFFF is treated as -1 !');
42.
43.   if 18446744073709551615 < 0 then
44.       Writeln('Uncast literal 18446744073709551615 is treated as -1 !');
45.
46. end.
47.
48.

Output:
Code: Bash  [Select][+][-]
1. fpc -B test.lpr
2. Free Pascal Compiler version 3.2.0 [2020/07/07] for x86_64
3. Copyright (c) 1993-2020 by Florian Klaempfl and others
4. Target OS: Linux for x86-64
5. Compiling test.lpr
6. test.lpr(19,9) Warning: range check error while evaluating constants (-1 must be between 0 and 18446744073709551615)
7. test.lpr(34,9) Warning: Comparison might be always false due to range of constant and expression
8. test.lpr(35,5) Warning: unreachable code
9. test.lpr(38,5) Warning: unreachable code
10. test.lpr(44,7) Warning: unreachable code
12. 47 lines compiled, 0.1 sec
13. 5 warning(s) issued
14. \$./test
15. Write variable and constant literal:
16. 18446744073709551615
17. -1
18. 18446744073709551615
19.
20. Write with IntToStr:
21. 18446744073709551615
22. -1
23. 18446744073709551615
24.
25. Uncast literal \$FFFFFFFFFFFFFFFF is treated as -1 !
26.
27.

The same thing happens in default FPC mode.

By side of "Warning: unreachable code", as well interesting warning is this:
Code: [Select]
`test.lpr(19,9) Warning: range check error while evaluating constants (-1 must be between 0 and 18446744073709551615)`
The compiler here contradict to itelf!

Now, if emailx45 can help us with results of the same code produced with Sydney, we will have  elementary facts for confirmation of suspicious that Delphi compatibility is broken here.
« Last Edit: August 08, 2020, 10:55:33 am by process_1 »

#### ASerge

• Hero Member
• Posts: 1665
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #47 on: August 08, 2020, 01:03:12 pm »
I think the main complaint is the difference between FPC and Delphi in interpretation of hexadecimal (only!) and 64-bit (only!) constants as a signed. And this fact is not documented. Example:
Code: Pascal  [Select][+][-]
1. {\$IFDEF PFC}{\$MODE OBJFPC}{\$ENDIF}
2. {\$APPTYPE CONSOLE}
3.
4. uses SysUtils;
5.
6. procedure Print64(const S: string; N: UInt64); overload;
7. begin
8.   Writeln(S, ' is unsigned ', N);
9. end;
10.
11. procedure Print64(const S: string; N: Int64); overload;
12. begin
13.   Writeln(S, ' is signed ', N);
14. end;
15.
16. procedure Print32(const S: string; N: UInt32); overload;
17. begin
18.   Writeln(S, ' is unsigned ', N);
19. end;
20.
21. procedure Print32(const S: string; N: Int32); overload;
22. begin
23.   Writeln(S, ' is signed ', N);
24. end;
25.
26. const
27.   Literal64Dec = 18446744073709551615;
28.   Literal64Hex = \$FFFFFFFFFFFFFFFF;
29.   Literal32Dec = 4294967295;
30.   Literal32Hex = \$FFFFFFFF;
31. var
32.   Variable64: UInt64 = Literal64Dec;
33.   Variable32: UInt32 = Literal32Dec;
34. begin
35.   Print64('Literal64Dec', Literal64Dec);
36.   Print64('Literal64Hex', Literal64Hex);
37.   Print64('Variable64', Variable64);
38.   Print32('Literal32Dec', Literal32Dec);
39.   Print32('Literal32Hex', Literal32Hex);
40.   Print32('Variable32', Variable32);
42. end.

FPC (32 or 64) output:
Quote
Literal64Dec is unsigned 18446744073709551615
Literal64Hex is signed -1
Variable64 is unsigned 18446744073709551615
Literal32Dec is unsigned 4294967295
Literal32Hex is unsigned 4294967295
Variable32 is unsigned 4294967295

Delphi (32 or 64) output:
Quote
Literal64Dec is unsigned 18446744073709551615
Literal64Hex is unsigned 18446744073709551615
Variable64 is unsigned 18446744073709551615
Literal32Dec is unsigned 4294967295
Literal32Hex is unsigned 4294967295
Variable32 is unsigned 4294967295

#### PascalDragon

• Hero Member
• Posts: 2093
• Compiler Developer
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #48 on: August 08, 2020, 06:42:12 pm »

Why should there be some warning or error? This is a perfectly valid Int64 number... If you'd use LongInt instead then the compiler will complain.

No no no.

\$FFFFFFFFF is not a valid int64/uint64. (9 x F !!!!)

This has a value of 2^68

This is with a 64 bit integer logic not representable.

But a wrong value is shown without a hint or an error.
That is not ok.

Ehm... you are aware that \$FFFFFFFFF (9 Fs) is (2^36 - 1), not (2^68 - 1)? High(QWord) has this value after all: \$FFFFFFFFFFFFFFFF.

I think the main complaint is the difference between FPC and Delphi in interpretation of hexadecimal (only!) and 64-bit (only!) constants as a signed. And this fact is not documented.

It is documented:

Quote
Remark The compiler decides on the type of an integer constant based on the value: An integer constant gets the smallest possible signed type. The first match in table (3.3) is used.

#### ASerge

• Hero Member
• Posts: 1665
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #49 on: August 08, 2020, 07:04:16 pm »
Remark The compiler decides on the type of an integer constant based on the value: An integer constant gets the smallest possible signed type. The first match in table (3.3) is used.
Did you read my post?
18446744073709551615 is UInt64. Unsigned because this value does not fit into Int64. But \$FFFFFFFFFFFFFFFF is already Int64. It also doesn't fit into Int64. Moreover, the hexadecimal form assumes the unsigned form (do you often see -\$...?).
Let the compiler developers choose this, but in my opinion it's need to document that only for hexadecimal constants and only large ones (higher (Int64)) the constant is selected as negative. This is not the case for the other bits or decimal representation.

#### process_1

• Guest
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #50 on: August 08, 2020, 07:53:43 pm »
Did you read my post?
18446744073709551615 is UInt64. Unsigned because this value does not fit into Int64. But \$FFFFFFFFFFFFFFFF is already Int64. It also doesn't fit into Int64. Moreover, the hexadecimal form assumes the unsigned form (do you often see -\$...?).

Just do not bother yourself trying to explain them, it is useless. I have gave up already.
« Last Edit: August 08, 2020, 08:03:25 pm by process_1 »

#### nanobit

• Jr. Member
• Posts: 78
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #51 on: August 08, 2020, 08:25:55 pm »
Quote
Remark The compiler decides on the type of an integer constant based on the value: An integer constant gets the smallest possible signed type. The first match in table (3.3) is used.

This quote does not explain hexadecimal literals which behave more like this in FPC:
Every untyped hexadecimal literal smaller than 8 bytes is implicitly extended with zero-bits,
then interpreted as int64(bitpattern). And finally, the storage-size of the int64 value is reduced if possible.
In practice, most hex literals have implicit (byte7 = \$00), thus they have a non-negative value.
The storage type can be signed or unsigned.

For hex literal \$FFFFFFFFFFFFFFFF and other 64 bit-values with leading 1-bit:
Delphi prefers uint64, but also supports implicit cast (reinterpretation) to provided int64 targets.
But a simpler rule would be more consistent: For negative constants, explicit typecasting is sufficient also for 64 bit, analogously to explicit typecast (in FPC and Delphi) for assigning hex literals to signed targets which have less than 64 bits. Example:
someShortInt := \$FF; // out-of-range (disallowed) in FPC/Delphi
someShortInt := shortint(\$FF); // -1 in FPC/Delphi

In Delphi is:
i64 := -1;
assert( i64 <> \$FFFFFFFFFFFFFFFF);
assert( i64 = int64(\$FFFFFFFFFFFFFFFF));

In FPC is:
assert( i64 = \$FFFFFFFFFFFFFFFF);
« Last Edit: August 09, 2020, 09:08:47 am by nanobit »

#### Warfley

• Sr. Member
• Posts: 302
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #52 on: August 08, 2020, 08:53:15 pm »
It is documented:

Quote
Remark The compiler decides on the type of an integer constant based on the value: An integer constant gets the smallest possible signed type. The first match in table (3.3) is used.

There is no signed type that can fit \$FFFFFFFFFFFFFFFF, because this is just another way of writing 18446744073709551615.
Note that \$XXXX are Hexadecimal numbers, not bit patterns, the documentation (https://www.freepascal.org/docs-html/current/ref/refse6.html#x17-160001.6) does cleary define this as a number.
So that \$FFFFFFFFFFFFFFFF is -1 is clearly wrong, because -1 in hex is -\$1.

So what happens here is a. either hex numbers don't refer to numbers but bit patterns, in this case the documentation is simply wrong, or b. this results in an overflow because there is no signed integer type that can fit \$FFFFFFFFFFFFFFFF, which is not covered by the documentation.
In the letter case there is also an inconsitency, because 18446744073709551615 does use qword but \$FFFFFFFFFFFFFFFF does not, but both are according to the documentation "numbers".

So either the documentation is wrong and hexadecimal referrs to bit patterns and not numbers, or the FPC is inconsitent on how it treats numbers of different formats and this is not documented

#### jamie

• Hero Member
• Posts: 3507
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #53 on: August 08, 2020, 08:59:19 pm »
Did you read my post?
18446744073709551615 is UInt64. Unsigned because this value does not fit into Int64. But \$FFFFFFFFFFFFFFFF is already Int64. It also doesn't fit into Int64. Moreover, the hexadecimal form assumes the unsigned form (do you often see -\$...?).

Just do not bother yourself trying to explain them, it is useless. I have gave up already.
Personally I think you should give up..

I've been around the camp for a long time, used all kinds of tools in the past and I just can't believe what I am reading here from those that should  know better. Actually I think do know better but we won't go there as it's most likely hurting now, I don't want to pile on the agony.

Also, because it happens to be a HEX number does not make it any different.. You can place a "-" in front of a hex number can get minus numbers from Hex notations.
This also is the same for OCTALS, bins etc..

by default the untyped numerical constant should result to a Integer type when it dominates the equation. Domination is when its on the left thus being the starting type and can only be changed via a CAST around it while on the left as the starting type..
You should not ever need to cast a untyped numerical constant while it's being put in play with a known type of the left because it should know enough to adapt to it..

This flaw in the compiler which does not exist in Delphi is also the cause for many of the overloads calling the wrong functions when ever constants come into play within Parameters …

So my advise to you is to give it up, throw in the towel and use something else..

I've been forced to use Delphi lately, I hate the IDE but I tell  you this, the compiler does not suffer from these issues, it does however lack some features fpc does have,  for Type helpers etc. I am sure Delphi will fix this one day but its not a cause of bad code generation.
The only true wisdom is knowing you know nothing

#### marcov

• Global Moderator
• Hero Member
• Posts: 8715
• FPC developer.
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #54 on: August 09, 2020, 12:50:02 pm »
Remark The compiler decides on the type of an integer constant based on the value: An integer constant gets the smallest possible signed type. The first match in table (3.3) is used.
Did you read my post?
18446744073709551615 is UInt64. Unsigned because this value does not fit into Int64. But \$FFFFFFFFFFFFFFFF is already Int64. It also doesn't fit into Int64. Moreover, the hexadecimal form assumes the unsigned form (do you often see -\$...?).
Let the compiler developers choose this, but in my opinion it's need to document that only for hexadecimal constants and only large ones (higher (Int64)) the constant is selected as negative. This is not the case for the other bits or decimal representation.

If I read FPK's explanation, then I do think that maybe some damage control can be done (and we might have to eventually for Delphi compat),  but keep in mind that that won't fix the fundamental problems with uint64, as soon as you start to do operations.

But IMHO this is all the sore itching of an essentially rare warning, and the whole "something must be done now" sentiment is overblown. It is an edge case.

That's why I tried to steer Process_1 in the direction of characterization of the Delphi situation (e.g. what does VAL do etc), but he only wanted to vent "just adopt C/C++" conspiracy theories and blame the moderators/developers, not actually do or research something.
« Last Edit: August 09, 2020, 01:32:30 pm by marcov »

#### emailx45

• New member
• Posts: 8
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #55 on: August 09, 2020, 10:01:50 pm »
hello people,
...

Thank you in advance.

EDIT: Added code to write integers directly, by side with IntToStr().

Quote
Code: Pascal  [Select][+][-]
1. program Project1;
2.
3. {\$APPTYPE CONSOLE}
4. {\$R *.res}
5.
6. uses
7.   System.SysUtils;
8.
9. var
10.   qw: UInt64;
11.
12. begin
13.   //
14.   qw := \$FFFFFFFFFFFFFFFF;
15.   //
16.   Writeln('Write variable and constant literal');
17.   //
18.   Writeln(qw);
19.   Writeln(\$FFFFFFFFFFFFFFFF);
20.   //
21.   Writeln;
22.   Writeln('Write with IntToStr:');
23.   //
24.   Writeln(IntToStr(qw), ' ***  ', qw);
25.   Writeln(IntToStr(\$FFFFFFFFFFFFFFFF), ' ***  ', \$FFFFFFFFFFFFFFFF);
26.   //
27.   if qw < 0 then
28.     Writeln('Uncast unsigned QWORD is less than 0!?!');
29.   //
30.   if UInt64(\$FFFFFFFFFFFFFFFF) < 0 then
31.     Writeln('Cast unsigned UInt64 is less than 0!?!');
32.   //
33.   if \$FFFFFFFFFFFFFFFF < 0 then
34.     Writeln('Uncast literal \$FFFFFFFFFFFFFFFF is treated as -1 !');
35.   //
37.
38. end.
39.

Quote
Code: Pascal  [Select][+][-]
1. Thread Start: Thread ID: 2688. Process Project1.exe (2300)
2. Process Start: D:\RADTests\Rio1033\Win32\Debug\Project1.exe. Base Address: \$00400000. Process Project1.exe (2300)
3. Module Load: Project1.exe. Has Debug Info. Base Address: \$00400000. Process Project1.exe (2300)
4. Module Load: ntdll.dll. No Debug Info. Base Address: \$77070000. Process Project1.exe (2300)
5. Module Load: KERNEL32.dll. No Debug Info. Base Address: \$75820000. Process Project1.exe (2300)
6. Module Load: KERNELBASE.dll. No Debug Info. Base Address: \$753A0000. Process Project1.exe (2300)
7. Thread Start: Thread ID: 4112. Process Project1.exe (2300)
8. Module Load: USER32.dll. No Debug Info. Base Address: \$755A0000. Process Project1.exe (2300)
9. Module Load: win32u.dll. No Debug Info. Base Address: \$76140000. Process Project1.exe (2300)
10. Module Load: VERSION.dll. No Debug Info. Base Address: \$74820000. Process Project1.exe (2300)
11. Thread Start: Thread ID: 10020. Process Project1.exe (2300)
12. Module Load: GDI32.dll. No Debug Info. Base Address: \$77030000. Process Project1.exe (2300)
13. Module Load: msvcrt.dll. No Debug Info. Base Address: \$75ED0000. Process Project1.exe (2300)
14. Module Load: gdi32full.dll. No Debug Info. Base Address: \$76440000. Process Project1.exe (2300)
15. Thread Start: Thread ID: 9640. Process Project1.exe (2300)
16. Module Load: msvcp_win.dll. No Debug Info. Base Address: \$76090000. Process Project1.exe (2300)
17. Module Load: ucrtbase.dll. No Debug Info. Base Address: \$74AB0000. Process Project1.exe (2300)
18. Module Load: OLEAUT32.dll. No Debug Info. Base Address: \$74C70000. Process Project1.exe (2300)
19. Module Load: combase.dll. No Debug Info. Base Address: \$761C0000. Process Project1.exe (2300)
20. Module Load: RPCRT4.dll. No Debug Info. Base Address: \$751E0000. Process Project1.exe (2300)
21. Module Load: SspiCli.dll. No Debug Info. Base Address: \$74840000. Process Project1.exe (2300)
22. Module Load: CRYPTBASE.dll. No Debug Info. Base Address: \$74830000. Process Project1.exe (2300)
23. Module Load: bcryptPrimitives.dll. No Debug Info. Base Address: \$757C0000. Process Project1.exe (2300)
24. Module Load: SECHOST.dll. No Debug Info. Base Address: \$75740000. Process Project1.exe (2300)
25. Module Load: ADVAPI32.dll. No Debug Info. Base Address: \$767B0000. Process Project1.exe (2300)
26. Module Load: NETAPI32.dll. No Debug Info. Base Address: \$72810000. Process Project1.exe (2300)
27. Module Load: netutils.dll. No Debug Info. Base Address: \$72780000. Process Project1.exe (2300)
28. Module Load: IMM32.dll. No Debug Info. Base Address: \$74C30000. Process Project1.exe (2300)
29. Thread Exit: Thread ID: 9640. Process Project1.exe (2300)
30. Thread Exit: Thread ID: 4112. Process Project1.exe (2300)
31. Thread Exit: Thread ID: 10020. Process Project1.exe (2300)
32.

Quote
~
Code: Pascal  [Select][+][-]
1. Checking project dependencies...
2. Compiling Project1.dproj (Debug, Win32)
3. dcc32 command line for "Project1.dpr"
4.   c:\emb\radstudiorio\200\bin\dcc32.exe -\$O- -\$W+ --no-config -M -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;
5.   Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG
18.   -CC -V -VN -NBC:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp -NHC:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win32 -NO.\Win32\Debug
19.   Project1.dpr
20. [dcc32 Warning] Project1.dpr(25): W1012 Constant expression violates subrange bounds
21. Success
22. Elapsed time: 00:00:00.3
23.
« Last Edit: August 10, 2020, 12:16:00 am by emailx45 »

#### emailx45

• New member
• Posts: 8
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #56 on: August 09, 2020, 10:33:05 pm »
Thank you julkas, once again!
Let see how FPC works in Delphi mode:

The compiler here contradict to itelf!

Now, if emailx45 can help us with results of the same code produced with Sydney, we will have  elementary facts for confirmation of suspicious that Delphi compatibility is broken here.

RAD STUDIO 10.3.3 ARCH 32bits - no-debugging
Quote
Code: Pascal  [Select][+][-]
1. Checking project dependencies...
2. Compiling Project1.dproj (Debug, Win32)
3. dcc32 command line for "Project1.dpr"
4.   c:\emb\radstudiorio\200\bin\dcc32.exe -\$O- -\$W+ --no-config -M -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;
5.   Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG
18.   -CC -V -VN -NBC:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp -NHC:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win32 -NO.\Win32\Debug
19.   Project1.dpr
20. [dcc32 Warning] Project1.dpr(35): W1012 Constant expression violates subrange bounds
21. [dcc32 Warning] Project1.dpr(36): W1012 Constant expression violates subrange bounds
22. Success
23. Elapsed time: 00:00:00.2
24.

Quote
Code: Pascal  [Select][+][-]
1. program Project1;
2.
3. {\$APPTYPE CONSOLE}
4. {\$R *.res}
5. {\$IFDEF FPC}
6. {\$MODE Delphi}
7. {\$ENDIF}
8.
9. uses
10.   SysUtils;
11.
12. {\$IFNDEF FPC}
13.
14. type
15.   QWord = UInt64;
16.   {\$ENDIF}
17.
18. var
19.   qw: QWord;
20.
21. begin
22.
23.   qw := \$FFFFFFFFFFFFFFFF;
24.
25.   Writeln('Write variable and constant literal:');
26.   Writeln(qw, ' **** ', qw);
27.   Writeln(\$FFFFFFFFFFFFFFFF, ' **** ', \$FFFFFFFFFFFFFFFF);
28.   Writeln(18446744073709551615, ' **** ', 18446744073709551615);
29.
30.   Writeln;
31.   Writeln('Write with IntToStr:');
32.   Writeln(IntToStr(qw),' **** ', qw);
33.   //
34.   {\$R-}     // ignoring range checking = compile!
35.   Writeln(IntToStr(\$FFFFFFFFFFFFFFFF),' **** ', \$FFFFFFFFFFFFFFFF);
36.   Writeln(IntToStr(18446744073709551615),' **** ', 18446744073709551615);
37.   {\$R+}
38.   //
39.   Writeln;
40.
41.   if qw < 0 then
42.     Writeln('Uncast unsigned QWORD is less than 0!?!');
43.
44.   if QWord(\$FFFFFFFFFFFFFFFF) < 0 then
45.     Writeln('Cast unsigned QWORD is less than 0!?!');
46.
47.   if \$FFFFFFFFFFFFFFFF < 0 then
48.     Writeln('Uncast literal \$FFFFFFFFFFFFFFFF is treated as -1 !');
49.
50.   if 18446744073709551615 < 0 then
51.     Writeln('Uncast literal 18446744073709551615 is treated as -1 !');
52.   //
54.
55. end.
56.

Quote
Code: Pascal  [Select][+][-]
1. Checking project dependencies...
2. Compiling Project1.dproj (Debug, Win32)
3. brcc32 command line for "Project1.vrc"
4.   c:\emb\radstudio210\bin\cgrc.exe -c65001 Project1.vrc -foProject1.res
5. dcc32 command line for "Project1.dpr"
6.   c:\emb\radstudio210\bin\dcc32.exe -\$O- -\$W+ --no-config -M -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;
7.   Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG
11.   -LNC:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp -NU.\Win32\Debug -NSWinapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;
19.   Project1.dpr
20. [dcc32 Warning] Project1.dpr(35): W1012 Constant expression violates subrange bounds
21. [dcc32 Warning] Project1.dpr(36): W1012 Constant expression violates subrange bounds
22. Success
23. Elapsed time: 00:00:01.1
24.

Quote
Code: Pascal  [Select][+][-]
1. program Project1;
2.
3. {\$APPTYPE CONSOLE}
4. {\$R *.res}
5. {\$IFDEF FPC}
6. {\$MODE Delphi}
7. {\$ENDIF}
8.
9. uses
10.   SysUtils;
11.
12. {\$IFNDEF FPC}
13.
14. type
15.   QWord = UInt64;
16.   {\$ENDIF}
17.
18. var
19.   qw: QWord;
20.
21. begin
22.
23.   qw := \$FFFFFFFFFFFFFFFF;
24.
25.   Writeln('Write variable and constant literal:');
26.   Writeln(qw, ' **** ', qw);
27.   Writeln(\$FFFFFFFFFFFFFFFF, ' **** ', \$FFFFFFFFFFFFFFFF);
28.   Writeln(18446744073709551615, ' **** ', 18446744073709551615);
29.
30.   Writeln;
31.   Writeln('Write with IntToStr:');
32.   Writeln(IntToStr(qw),' **** ', qw);
33.   //
34.   {\$R-}     // ignoring range checking = compile!
35.   Writeln(IntToStr(\$FFFFFFFFFFFFFFFF),' **** ', \$FFFFFFFFFFFFFFFF);
36.   Writeln(IntToStr(18446744073709551615),' **** ', 18446744073709551615);
37.   {\$R+}
38.   //
39.   Writeln;
40.
41.   if qw < 0 then
42.     Writeln('Uncast unsigned QWORD is less than 0!?!');
43.
44.   if QWord(\$FFFFFFFFFFFFFFFF) < 0 then
45.     Writeln('Cast unsigned QWORD is less than 0!?!');
46.
47.   if \$FFFFFFFFFFFFFFFF < 0 then
48.     Writeln('Uncast literal \$FFFFFFFFFFFFFFFF is treated as -1 !');
49.
50.   if 18446744073709551615 < 0 then
51.     Writeln('Uncast literal 18446744073709551615 is treated as -1 !');
52.   //
54.
55. end.
56.

« Last Edit: August 10, 2020, 12:17:15 am by emailx45 »

#### emailx45

• New member
• Posts: 8
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #57 on: August 09, 2020, 10:36:04 pm »
RAD Studio 10.3.3 Arch 64bits no-debugging
Quote
Code: Pascal  [Select][+][-]
1. Checking project dependencies...
2. Compiling Project1.dproj (Debug, Win64)
3. brcc32 command line for "Project1.vrc"
4.   c:\emb\radstudiorio\200\bin\cgrc.exe -c65001 Project1.vrc -foProject1.res
5. dcc64 command line for "Project1.dpr"
6.   c:\emb\radstudiorio\200\bin\dcc64.exe -\$O- -\$W+ --no-config -M -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;
7.   Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG
12.   -LNC:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64 -NU.\Win64\Debug -NSWinapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;
21.   C:\EMB\FastReport\LIBD26x64 -CC -V -VN -VR -NBC:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64
22.   -NHC:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win64 -NO.\Win64\Debug  Project1.dpr
23. [dcc64 Warning] Project1.dpr(35): W1012 Constant expression violates subrange bounds
24. [dcc64 Warning] Project1.dpr(36): W1012 Constant expression violates subrange bounds
25. Success
26. Elapsed time: 00:00:00.3
27.

Quote
Code: Pascal  [Select][+][-]
1. program Project1;
2.
3. {\$APPTYPE CONSOLE}
4. {\$R *.res}
5. {\$IFDEF FPC}
6. {\$MODE Delphi}
7. {\$ENDIF}
8.
9. uses
10.   SysUtils;
11.
12. {\$IFNDEF FPC}
13.
14. type
15.   QWord = UInt64;
16.   {\$ENDIF}
17.
18. var
19.   qw: QWord;
20.
21. begin
22.
23.   qw := \$FFFFFFFFFFFFFFFF;
24.
25.   Writeln('Write variable and constant literal:');
26.   Writeln(qw, ' **** ', qw);
27.   Writeln(\$FFFFFFFFFFFFFFFF, ' **** ', \$FFFFFFFFFFFFFFFF);
28.   Writeln(18446744073709551615, ' **** ', 18446744073709551615);
29.
30.   Writeln;
31.   Writeln('Write with IntToStr:');
32.   Writeln(IntToStr(qw),' **** ', qw);
33.   //
34.   {\$R-}     // ignoring range checking = compile!
35.   Writeln(IntToStr(\$FFFFFFFFFFFFFFFF),' **** ', \$FFFFFFFFFFFFFFFF);
36.   Writeln(IntToStr(18446744073709551615),' **** ', 18446744073709551615);
37.   {\$R+}
38.   //
39.   Writeln;
40.
41.   if qw < 0 then
42.     Writeln('Uncast unsigned QWORD is less than 0!?!');
43.
44.   if QWord(\$FFFFFFFFFFFFFFFF) < 0 then
45.     Writeln('Cast unsigned QWORD is less than 0!?!');
46.
47.   if \$FFFFFFFFFFFFFFFF < 0 then
48.     Writeln('Uncast literal \$FFFFFFFFFFFFFFFF is treated as -1 !');
49.
50.   if 18446744073709551615 < 0 then
51.     Writeln('Uncast literal 18446744073709551615 is treated as -1 !');
52.   //
54.
55. end.
56.

« Last Edit: August 10, 2020, 12:17:53 am by emailx45 »

#### emailx45

• New member
• Posts: 8
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #58 on: August 09, 2020, 10:39:54 pm »
RAD Studio 10.4 Sydney 64bits no-debugging

Quote
Code: Pascal  [Select][+][-]
1. Checking project dependencies...
2. Compiling Project1.dproj (Debug, Win64)
3. brcc32 command line for "Project1.vrc"
4.   c:\emb\radstudio210\bin\cgrc.exe -c65001 Project1.vrc -foProject1.res
5. dcc64 command line for "Project1.dpr"
6.   c:\emb\radstudio210\bin\dcc64.exe -\$O- -\$W+ --no-config -M -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;
7.   Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG
21.   Project1.dpr
22. [dcc64 Warning] Project1.dpr(35): W1012 Constant expression violates subrange bounds
23. [dcc64 Warning] Project1.dpr(36): W1012 Constant expression violates subrange bounds
24. Success
25. Elapsed time: 00:00:00.2
26.

Quote
Code: Pascal  [Select][+][-]
1. program Project1;
2.
3. {\$APPTYPE CONSOLE}
4. {\$R *.res}
5. {\$IFDEF FPC}
6. {\$MODE Delphi}
7. {\$ENDIF}
8.
9. uses
10.   SysUtils;
11.
12. {\$IFNDEF FPC}
13.
14. type
15.   QWord = UInt64;
16.   {\$ENDIF}
17.
18. var
19.   qw: QWord;
20.
21. begin
22.
23.   qw := \$FFFFFFFFFFFFFFFF;
24.
25.   Writeln('Write variable and constant literal:');
26.   Writeln(qw, ' **** ', qw);
27.   Writeln(\$FFFFFFFFFFFFFFFF, ' **** ', \$FFFFFFFFFFFFFFFF);
28.   Writeln(18446744073709551615, ' **** ', 18446744073709551615);
29.
30.   Writeln;
31.   Writeln('Write with IntToStr:');
32.   Writeln(IntToStr(qw),' **** ', qw);
33.   //
34.   {\$R-}     // ignoring range checking = compile!
35.   Writeln(IntToStr(\$FFFFFFFFFFFFFFFF),' **** ', \$FFFFFFFFFFFFFFFF);
36.   Writeln(IntToStr(18446744073709551615),' **** ', 18446744073709551615);
37.   {\$R+}
38.   //
39.   Writeln;
40.
41.   if qw < 0 then
42.     Writeln('Uncast unsigned QWORD is less than 0!?!');
43.
44.   if QWord(\$FFFFFFFFFFFFFFFF) < 0 then
45.     Writeln('Cast unsigned QWORD is less than 0!?!');
46.
47.   if \$FFFFFFFFFFFFFFFF < 0 then
48.     Writeln('Uncast literal \$FFFFFFFFFFFFFFFF is treated as -1 !');
49.
50.   if 18446744073709551615 < 0 then
51.     Writeln('Uncast literal 18446744073709551615 is treated as -1 !');
52.   //
54.
55. end.
56.
« Last Edit: August 10, 2020, 12:18:28 am by emailx45 »

#### emailx45

• New member
• Posts: 8
##### Re: Implicit converison, literals and QWORD variable warning
« Reply #59 on: August 09, 2020, 10:56:31 pm »
here "why" the inttostr() works with Limits in 32/64bit value

RAD Studio 10.3.3 Rio  or RAD Studio 10.4 Sydney = same procedures

INTEGER: Represents a signed 32-bit integer type.
Integer represents a subset of the integer numbers. The range for the Integer type is from -2147483648 through 2147483647.
The size of Integer is 32 bits across all 64-bit and 32-bit platforms.

INT64: Defines a 64-bit signed integer type.
Int64 represents a subset of the integer numbers. The range for the Int64 type is from -2^63 through 2^63-1.
The size of Int64 is 64 bits across all 64-bit and 32-bit platforms

CARDINAL: Represents an unsigned 32-bit integer type.
Cardinal represents a subset of the natural numbers. The range for the Cardinal type is from 0 through 4294967295.
The size of Cardinal is 32 bits across all 64-bit and 32-bit platforms.

UINT64: 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.

Quote
Code: Pascal  [Select][+][-]
1. function IntToStr(Value: Integer): string;
2. begin
3.   if Value < 0 then
4.     Result := _IntToStr32(-Value, True)
5.   else
6.     Result := _IntToStr32(Value, False);
7. end;
8.

Code: Pascal  [Select][+][-]
1. function IntToStr(Value: Int64): string;
2. begin
3.   if Value < 0 then
4.     Result := _IntToStr64(-Value, True)
5.   else
6.     Result := _IntToStr64(Value, False);
7. end;
8.

Code: Pascal  [Select][+][-]
1. function UIntToStr(Value: Cardinal): string;
2. begin
3.   Result := _IntToStr32(Value, False);
4. end;
5.

Code: Pascal  [Select][+][-]
1. function UIntToStr(Value: UInt64): string;
2. begin
3.   Result := _IntToStr64(Value, False);
4. end;
5.

***********************
Code: Pascal  [Select][+][-]
1. function _IntToStr32(Value: Cardinal; Negative: Boolean): string;
2. var
3.   I, J, K : Cardinal;
4.   Digits  : Integer;
5.   P       : PChar;
6.   NewLen  : Integer;
7. begin
8.   I := Value;
9.   if I >= 10000 then
10.     if I >= 1000000 then
11.       if I >= 100000000 then
12.         Digits := 9 + Ord(I >= 1000000000)
13.       else
14.         Digits := 7 + Ord(I >= 10000000)
15.     else
16.       Digits := 5 + Ord(I >= 100000)
17.   else
18.     if I >= 100 then
19.       Digits := 3 + Ord(I >= 1000)
20.     else
21.       Digits := 1 + Ord(I >= 10);
22.   NewLen  := Digits + Ord(Negative);
23.   SetLength(Result, NewLen);
24.   P := PChar(Result);
25.   P^ := '-';
26.   Inc(P, Ord(Negative));
27.   if Digits > 2 then
28.     repeat
29.       J  := I div 100;           {Dividend div 100}
30.       K  := J * 100;
31.       K  := I - K;               {Dividend mod 100}
32.       I  := J;                   {Next Dividend}
33.       Dec(Digits, 2);
34.       PDWord(P + Digits)^ := DWord(TwoDigitLookup[K]);
35.     until Digits <= 2;
36.   if Digits = 2 then
37.     PDWord(P+ Digits-2)^ := DWord(TwoDigitLookup[I])
38.   else
39.     PChar(P)^ := Char(I or ord('0'));
40. end;
41.

Code: Pascal  [Select][+][-]
1. function _IntToStr64(Value: UInt64; Negative: Boolean): string;
2. var
3.   I64, J64, K64      : UInt64;
4.   I32, J32, K32, L32 : Cardinal;
5.   Digits             : Byte;
6.   P                  : PChar;
7.   NewLen             : Integer;
8. begin
9.   {Within Integer Range - Use Faster Integer Version}
10.   if (Negative and (Value <= High(Integer))) or
11.      (not Negative and (Value <= High(Cardinal))) then
12.     Exit(_IntToStr32(Value, Negative));
13.
14.   I64 := Value;
15.   if I64 >= 100000000000000 then
16.     if I64 >= 10000000000000000 then
17.       if I64 >= 1000000000000000000 then
18.         if I64 >= 10000000000000000000 then
19.           Digits := 20
20.         else
21.           Digits := 19
22.       else
23.         Digits := 17 + Ord(I64 >= 100000000000000000)
24.     else
25.       Digits := 15 + Ord(I64 >= 1000000000000000)
26.   else
27.     if I64 >= 1000000000000 then
28.       Digits := 13 + Ord(I64 >= 10000000000000)
29.     else
30.       if I64 >= 10000000000 then
31.         Digits := 11 + Ord(I64 >= 100000000000)
32.       else
33.         Digits := 10;
34.   NewLen  := Digits + Ord(Negative);
35.   SetLength(Result, NewLen);
36.   P := PChar(Result);
37.   P^ := '-';
38.   Inc(P, Ord(Negative));
39.   if Digits = 20 then
40.   begin
41.     P^ := '1';
42.     Inc(P);
43.     Dec(I64, 10000000000000000000);
44.     Dec(Digits);
45.   end;
46.   if Digits > 17 then
47.   begin {18 or 19 Digits}
48.     if Digits = 19 then
49.     begin
50.       P^ := '0';
51.       while I64 >= 1000000000000000000 do
52.       begin
53.         Dec(I64, 1000000000000000000);
54.         Inc(P^);
55.       end;
56.       Inc(P);
57.     end;
58.     P^ := '0';
59.     while I64 >= 100000000000000000 do
60.     begin
61.       Dec(I64, 100000000000000000);
62.       Inc(P^);
63.     end;
64.     Inc(P);
65.     Digits := 17;
66.   end;
67.   J64 := I64 div 100000000;
68.   K64 := I64 - (J64 * 100000000); {Remainder = 0..99999999}
69.   I32 := K64;
70.   J32 := I32 div 100;
71.   K32 := J32 * 100;
72.   K32 := I32 - K32;
73.   PDWord(P + Digits - 2)^ := DWord(TwoDigitLookup[K32]);
74.   I32 := J32 div 100;
75.   L32 := I32 * 100;
76.   L32 := J32 - L32;
77.   PDWord(P + Digits - 4)^ := DWord(TwoDigitLookup[L32]);
78.   J32 := I32 div 100;
79.   K32 := J32 * 100;
80.   K32 := I32 - K32;
81.   PDWord(P + Digits - 6)^ := DWord(TwoDigitLookup[K32]);
82.   PDWord(P + Digits - 8 )^ := DWord(TwoDigitLookup[J32]);
83.   Dec(Digits, 8 );
84.   I32 := J64; {Dividend now Fits within Integer - Use Faster Version}
85.   if Digits > 2 then
86.     repeat
87.       J32 := I32 div 100;
88.       K32 := J32 * 100;
89.       K32 := I32 - K32;
90.       I32 := J32;
91.       Dec(Digits, 2);
92.       PDWord(P + Digits)^ := DWord(TwoDigitLookup[K32]);
93.     until Digits <= 2;
94.   if Digits = 2 then
95.     PDWord(P + Digits-2)^ := DWord(TwoDigitLookup[I32])
96.   else
97.     P^ := Char(I32 or ord('0'));
98. end;
99.

« Last Edit: August 10, 2020, 12:20:24 am by emailx45 »