The Rio is the current version of Delphi, AFAIK
Can anyone who have Rio confirm all this?
As I wrote before, how can the compiler know if a certain bit pattern is to be interpreted as signed or unsigned given an untyped const?Easy. Tries to use a single-byte signed type that includes the value of a constant. If not, a single-byte unsigned type. If it doesn't work, then a two-byte signed type, and so on.
I don't believe Delphi 10.4 can do that, unless on use and with type inference, which would be BAD. Somebody is plain lying here....
About C++ integer literals - https://en.cppreference.com/w/cpp/language/integer_literal
From Notes -
There are no negative integer constants.
No suffix means signed. Since we have no suffix at all, we are in compliance O:-)
Seriously, the qword(literal value) on the rhs is probably equivalent to C++'s suffixes.
No suffix means signed. Since we have no suffix at all, we are in compliance O:-)
Seriously, the qword(literal value) on the rhs is probably equivalent to C++'s suffixes.
What julkas mentioned means exactly that - suffixes for integers are ignored in C++, they are always positive numbers. For negative numbers, negative sign is used.
Ok, I read better, and it say a negative literal generates a unsigned value + an unary minus operation. But how do you generate an operation for a constant? And what type does the constant have? It might be C/C++ substitution based parsing, trying to process that unary operation at every place the literal is used. I'm not sure Pascal works that way.
Moreover, as soon as you have binary operands, type promotion rules come out to play then it is not just the literal definition, but the whole evaluation on the place it is used.
p.s. As I said before: if you want to make a standards argument, you must base it purely on the text. Testing with a compiler clouds the issue with potentially implementation defined behaviour.
What julkas mentioned means exactly that - suffixes for integer literals are ignored in C++, they are always positive numbers. For negative numbers, negative sign is used. In C/C++ suffixes for hex numbers are L, LL, UL, ULL, but as wrote already, they are ignored in C++. Execute following code and you will see exact result of it:
Just post an example what you want to accomplish. Type promotion rules applies here without an issue.
Problem in FPC, however, is arbitrary rule for unwanted integer literals implicit conversion, as already pointed.
p.s. As I said before: if you want to make a standards argument, you must base it purely on the text. Testing with a compiler clouds the issue with potentially implementation defined behaviour.
All this talk about C/C++ is utterly useless.
They are like minimal rules. But not all behaviour that you see might be required, that 's what "implementation defined" means (and IIRC that is a term from K&R). See e.g. https://en.wikipedia.org/wiki/Unspecified_behaviorIn C and C++ there are also differences between implementation specific behaviour, unspecified behaviour and undefined behaviour, see: https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior
IOW two different C compilers might react different, but still be standards compliant. Therefore you can't advocate as anything GCC does as "the will of the standard". It might be one choice of many in the optional parts of the standard.
As $ffffffffffffffff (2^64-1) is accepted by val as an int64, it is handled as an int64. That's it. Very simple.Is it really simple? I mean you just supplied it a huge positive number and magically it turned to -1. That does not sound simple to me, to me that sounds like compiler magic doing something I didn't want it to do. Because if I wanted -1 to be there, I would have written -1 and didn't need to type the other 15 characters.
All this talk about C/C++ is utterly useless.
No body force you to read, nor to reply.
The benefit reading other standards is to learn how properly to handle problems in any compiler,
not to reinvent the wheel.
it seems some Pandora's boxes are opened in the core of FPC.
In this case consistency. But you constantly ignoring that, which is your problem and I do not really care about.
As $ffffffffffffffff (2^64-1) is accepted by val as an int64, it is handled as an int64. That's it. Very simple.Is it really simple?
Yes. If you do not ignore the text before as you did.Yes if you understand how it works understanding how it works is easy... I get it.
Back to you. But putting C/C++ mindlessly on some pedestal is not constructive.
Is it possible that the most of people here do not see this, even I places here several examples and background clearly show that consistency here is broken?
*sigh* The problem is that changing this will probably break a lot of code because before qword was available in delphi, people *assigned* $ffffffffffffffff to int64 and expected to get -1. We might be able to change this in the compiler by a switch for newer delphi versions but stuff like
*sigh* The problem is that changing this will probably break a lot of code because before qword was available in delphi, people *assigned* $ffffffffffffffff to int64 and expected to get -1. We might be able to change this in the compiler by a switch for newer delphi versions but stuff like
But why "lot of people" would place $ffffffffffffffff to int64 instead to simply -1?
Can someone please test with different delphi versions if it writes 'ok'? This is what it narrows down to: does val for int64 accept $ffffffffffffffff or not.
Back to you. But putting C/C++ mindlessly on some pedestal is not constructive.
What is not constructive? To read well established C/C++standards?
Ignoring fact that FPC turning uint64 constant literals to negative number is serious fundamental problem.
That is all about this "fuzz", someone here call it, already.
Is it possible that the most of people here do not see this, even I places here several examples and background clearly show that consistency here is broken?
https://community.idera.com/developer-tools/programming-languages/f/delphi-language/73050/freepascal-compatibility---how-is-this-kind-of-code-compiled-in-delphi-10-3-rio-or-10-4-sydney
And it has been known that time also that C sidesteps the issue by not having real constants, but substituting defines in target context, and evaluating there. A lucky coincidence rather than something solid from "standards", but with the consequence of slow compilation.C doesnt, but C++ has them
You haven't placed anything that isn't known for 20+ years. And has been analysed to death in that period, ever since there have been attempts to define an unsigned type that is the equivalent size of the chief signed type.
You didn't read or understand what I have wrote, I'm afraid.
What is "analyzed to death" 20+ years ago? How involving uint64 will cause problems?
Don't be theatrical,
please and write when uint64 in introduced by Delphi and when with FPC as native type.
AFAIK, that happens few years ago and as such is hardly "analyezed to death". I bet it was introduced in FPC without any deeper though about.
when with FPC as native type. AFAIK, that happens few years ago
Well, define few? 21 years is not few.
As $ffffffffffffffff (2^64-1) is accepted by val as an int64, it is handled as an int64. That's it. Very simple.Is it really simple? I mean you just supplied it a huge positive number and magically it turned to -1.
Hi!
While playing around with $FFFFFFFF and MaxUint I made a typo and detected a bug:
I typed 9xF instead of 8.
The result is astonishing:
2^36 = 68719476735
{16 * MaxDword}Bug report?
const nonsense = $FFFFFFFFF; // 9 x F var I : Int64; pw : single; s: string; begin I := nonsense; pw := log2(I); showMessage (FloatToStr(pw)); s := intToStr(nonsense); showMessage (s); end;
Winni
PS No error message from the compiler or at runtime.
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.
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 !!!!)
From the compiler's point of view this is not a “huge positive number”, but first and formost a number pattern that is then simply treated as a negative number which is perfectly legal for it the parser/scanner to do.But I am a human, why should I care how the compiler sees things? The compiler is basically just a human machine interface, so it should be as friendly to use as possible, from the human perspective.
But I am a human, why should I care how the compiler sees things? The compiler is basically just a human machine interface, so it should be as friendly to use as possible, from the human perspective.
I mean we could also start writing floats as IEEE 754 numbers, from the compiler point of view this makes a lot of sense. But that doesn't mean that it makes sense for a human.
The job of the compiler (and the programming language in general) is to make programming as humanly friendly as possible, this is the whole reason we don't write assembly
hello people,
...
Thank you very much, julkas.No problem. Code -
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):
Writeln(qw); Writeln($FFFFFFFFFFFFFFFF);
test.lpr(19,9) Warning: range check error while evaluating constants (-1 must be between 0 and 18446744073709551615)
Literal64Dec is unsigned 18446744073709551615
Literal64Hex is signed -1
Variable64 is unsigned 18446744073709551615
Literal32Dec is unsigned 4294967295
Literal32Hex is unsigned 4294967295
Variable32 is unsigned 4294967295
Literal64Dec is unsigned 18446744073709551615
Literal64Hex is unsigned 18446744073709551615
Variable64 is unsigned 18446744073709551615
Literal32Dec is unsigned 4294967295
Literal32Hex is unsigned 4294967295
Variable32 is unsigned 4294967295
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.
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.
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.
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?
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 -$...?).
QuoteRemark 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.
It is documented (https://www.freepascal.org/docs-html/current/ref/refsu4.html#x26-250003.1.1):QuoteRemark 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.
Personally I think you should give up..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.
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.
hello people,
...
Thank you in advance.
EDIT: Added code to write integers directly, by side with IntToStr().
program Project1; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; var qw: UInt64; begin // qw := $FFFFFFFFFFFFFFFF; // Writeln('Write variable and constant literal'); // Writeln(qw); Writeln($FFFFFFFFFFFFFFFF); // Writeln; Writeln('Write with IntToStr:'); // Writeln(IntToStr(qw), ' *** ', qw); Writeln(IntToStr($FFFFFFFFFFFFFFFF), ' *** ', $FFFFFFFFFFFFFFFF); // if qw < 0 then Writeln('Uncast unsigned QWORD is less than 0!?!'); // if UInt64($FFFFFFFFFFFFFFFF) < 0 then Writeln('Cast unsigned UInt64 is less than 0!?!'); // if $FFFFFFFFFFFFFFFF < 0 then Writeln('Uncast literal $FFFFFFFFFFFFFFFF is treated as -1 !'); // readln; end.
Thread Start: Thread ID: 2688. Process Project1.exe (2300) Process Start: D:\RADTests\Rio1033\Win32\Debug\Project1.exe. Base Address: $00400000. Process Project1.exe (2300) Module Load: Project1.exe. Has Debug Info. Base Address: $00400000. Process Project1.exe (2300) Module Load: ntdll.dll. No Debug Info. Base Address: $77070000. Process Project1.exe (2300) Module Load: KERNEL32.dll. No Debug Info. Base Address: $75820000. Process Project1.exe (2300) Module Load: KERNELBASE.dll. No Debug Info. Base Address: $753A0000. Process Project1.exe (2300) Thread Start: Thread ID: 4112. Process Project1.exe (2300) Module Load: USER32.dll. No Debug Info. Base Address: $755A0000. Process Project1.exe (2300) Module Load: win32u.dll. No Debug Info. Base Address: $76140000. Process Project1.exe (2300) Module Load: VERSION.dll. No Debug Info. Base Address: $74820000. Process Project1.exe (2300) Thread Start: Thread ID: 10020. Process Project1.exe (2300) Module Load: GDI32.dll. No Debug Info. Base Address: $77030000. Process Project1.exe (2300) Module Load: msvcrt.dll. No Debug Info. Base Address: $75ED0000. Process Project1.exe (2300) Module Load: gdi32full.dll. No Debug Info. Base Address: $76440000. Process Project1.exe (2300) Thread Start: Thread ID: 9640. Process Project1.exe (2300) Module Load: msvcp_win.dll. No Debug Info. Base Address: $76090000. Process Project1.exe (2300) Module Load: ucrtbase.dll. No Debug Info. Base Address: $74AB0000. Process Project1.exe (2300) Module Load: OLEAUT32.dll. No Debug Info. Base Address: $74C70000. Process Project1.exe (2300) Module Load: combase.dll. No Debug Info. Base Address: $761C0000. Process Project1.exe (2300) Module Load: RPCRT4.dll. No Debug Info. Base Address: $751E0000. Process Project1.exe (2300) Module Load: SspiCli.dll. No Debug Info. Base Address: $74840000. Process Project1.exe (2300) Module Load: CRYPTBASE.dll. No Debug Info. Base Address: $74830000. Process Project1.exe (2300) Module Load: bcryptPrimitives.dll. No Debug Info. Base Address: $757C0000. Process Project1.exe (2300) Module Load: SECHOST.dll. No Debug Info. Base Address: $75740000. Process Project1.exe (2300) Module Load: ADVAPI32.dll. No Debug Info. Base Address: $767B0000. Process Project1.exe (2300) Module Load: NETAPI32.dll. No Debug Info. Base Address: $72810000. Process Project1.exe (2300) Module Load: netutils.dll. No Debug Info. Base Address: $72780000. Process Project1.exe (2300) Module Load: IMM32.dll. No Debug Info. Base Address: $74C30000. Process Project1.exe (2300) Thread Exit: Thread ID: 9640. Process Project1.exe (2300) Thread Exit: Thread ID: 4112. Process Project1.exe (2300) Thread Exit: Thread ID: 10020. Process Project1.exe (2300)
~
Checking project dependencies... Compiling Project1.dproj (Debug, Win32) dcc32 command line for "Project1.dpr" c:\emb\radstudiorio\200\bin\dcc32.exe -$O- -$W+ --no-config -M -Q -TX.exe -AGenerics.Collections=System.Generics.Collections; Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG -E.\Win32\Debug -Ic:\emb\radstudiorio\200\lib\Win32\debug;C:\EMB\FirePower\source\Win32\Debug;c:\emb\radstudiorio\200\lib\Win32\release; C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports; C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26 -LEC:\Users\Public\Documents\Embarcadero\Studio\20.0\Bpl -LNC:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp -NU.\Win32\Debug -NSWinapi; System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;System;Xml;Data;Datasnap;Web;Soap; -Oc:\emb\radstudiorio\200\lib\Win32\release; C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports; C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26 -Rc:\emb\radstudiorio\200\lib\Win32\release;C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports; C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26 -Uc:\emb\radstudiorio\200\lib\Win32\debug;C:\EMB\FirePower\source\Win32\Debug;c:\emb\radstudiorio\200\lib\Win32\release; C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports; C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26 -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 Project1.dpr [dcc32 Warning] Project1.dpr(25): W1012 Constant expression violates subrange bounds Success Elapsed time: 00:00:00.3
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.
Checking project dependencies... Compiling Project1.dproj (Debug, Win32) dcc32 command line for "Project1.dpr" c:\emb\radstudiorio\200\bin\dcc32.exe -$O- -$W+ --no-config -M -Q -TX.exe -AGenerics.Collections=System.Generics.Collections; Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG -E.\Win32\Debug -Ic:\emb\radstudiorio\200\lib\Win32\debug;C:\EMB\FirePower\source\Win32\Debug;c:\emb\radstudiorio\200\lib\Win32\release; C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports; C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26 -LEC:\Users\Public\Documents\Embarcadero\Studio\20.0\Bpl -LNC:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp -NU.\Win32\Debug -NSWinapi; System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;System;Xml;Data;Datasnap;Web;Soap; -Oc:\emb\radstudiorio\200\lib\Win32\release; C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports; C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26 -Rc:\emb\radstudiorio\200\lib\Win32\release;C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports; C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26 -Uc:\emb\radstudiorio\200\lib\Win32\debug;C:\EMB\FirePower\source\Win32\Debug;c:\emb\radstudiorio\200\lib\Win32\release; C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports; C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26 -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 Project1.dpr [dcc32 Warning] Project1.dpr(35): W1012 Constant expression violates subrange bounds [dcc32 Warning] Project1.dpr(36): W1012 Constant expression violates subrange bounds Success Elapsed time: 00:00:00.2
program Project1; {$APPTYPE CONSOLE} {$R *.res} {$IFDEF FPC} {$MODE Delphi} {$ENDIF} uses SysUtils; {$IFNDEF FPC} type QWord = UInt64; {$ENDIF} var qw: QWord; begin qw := $FFFFFFFFFFFFFFFF; Writeln('Write variable and constant literal:'); Writeln(qw, ' **** ', qw); Writeln($FFFFFFFFFFFFFFFF, ' **** ', $FFFFFFFFFFFFFFFF); Writeln(18446744073709551615, ' **** ', 18446744073709551615); Writeln; Writeln('Write with IntToStr:'); Writeln(IntToStr(qw),' **** ', qw); // {$R-} // ignoring range checking = compile! Writeln(IntToStr($FFFFFFFFFFFFFFFF),' **** ', $FFFFFFFFFFFFFFFF); Writeln(IntToStr(18446744073709551615),' **** ', 18446744073709551615); {$R+} // Writeln; if qw < 0 then Writeln('Uncast unsigned QWORD is less than 0!?!'); if QWord($FFFFFFFFFFFFFFFF) < 0 then Writeln('Cast unsigned QWORD is less than 0!?!'); if $FFFFFFFFFFFFFFFF < 0 then Writeln('Uncast literal $FFFFFFFFFFFFFFFF is treated as -1 !'); if 18446744073709551615 < 0 then Writeln('Uncast literal 18446744073709551615 is treated as -1 !'); // readln; end.
Checking project dependencies... Compiling Project1.dproj (Debug, Win32) brcc32 command line for "Project1.vrc" c:\emb\radstudio210\bin\cgrc.exe -c65001 Project1.vrc -foProject1.res dcc32 command line for "Project1.dpr" c:\emb\radstudio210\bin\dcc32.exe -$O- -$W+ --no-config -M -Q -TX.exe -AGenerics.Collections=System.Generics.Collections; Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG -E.\Win32\Debug -Ic:\emb\radstudio210\lib\Win32\debug;C:\Emb\QuickReport\Win32\Debug;c:\emb\radstudio210\lib\Win32\release; C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports;c:\emb\radstudio210\Imports;C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp; c:\emb\radstudio210\include;C:\Emb\QuickReport\src -LEC:\Users\Public\Documents\Embarcadero\Studio\21.0\Bpl -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; System;Xml;Data;Datasnap;Web;Soap; -Oc:\emb\radstudio210\lib\Win32\release;C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports; c:\emb\radstudio210\Imports;C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp;c:\emb\radstudio210\include;C:\Emb\QuickReport\src -Rc:\emb\radstudio210\lib\Win32\release;C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports;c:\emb\radstudio210\Imports; C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp;c:\emb\radstudio210\include;C:\Emb\QuickReport\src -Uc:\emb\radstudio210\lib\Win32\debug; C:\Emb\QuickReport\Win32\Debug;c:\emb\radstudio210\lib\Win32\release;C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports; c:\emb\radstudio210\Imports;C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp;c:\emb\radstudio210\include;C:\Emb\QuickReport\src -CC -V -VN -NBC:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp -NHC:\Users\Public\Documents\Embarcadero\Studio\21.0\hpp\Win32 -NO.\Win32\Debug Project1.dpr [dcc32 Warning] Project1.dpr(35): W1012 Constant expression violates subrange bounds [dcc32 Warning] Project1.dpr(36): W1012 Constant expression violates subrange bounds Success Elapsed time: 00:00:01.1
program Project1; {$APPTYPE CONSOLE} {$R *.res} {$IFDEF FPC} {$MODE Delphi} {$ENDIF} uses SysUtils; {$IFNDEF FPC} type QWord = UInt64; {$ENDIF} var qw: QWord; begin qw := $FFFFFFFFFFFFFFFF; Writeln('Write variable and constant literal:'); Writeln(qw, ' **** ', qw); Writeln($FFFFFFFFFFFFFFFF, ' **** ', $FFFFFFFFFFFFFFFF); Writeln(18446744073709551615, ' **** ', 18446744073709551615); Writeln; Writeln('Write with IntToStr:'); Writeln(IntToStr(qw),' **** ', qw); // {$R-} // ignoring range checking = compile! Writeln(IntToStr($FFFFFFFFFFFFFFFF),' **** ', $FFFFFFFFFFFFFFFF); Writeln(IntToStr(18446744073709551615),' **** ', 18446744073709551615); {$R+} // Writeln; if qw < 0 then Writeln('Uncast unsigned QWORD is less than 0!?!'); if QWord($FFFFFFFFFFFFFFFF) < 0 then Writeln('Cast unsigned QWORD is less than 0!?!'); if $FFFFFFFFFFFFFFFF < 0 then Writeln('Uncast literal $FFFFFFFFFFFFFFFF is treated as -1 !'); if 18446744073709551615 < 0 then Writeln('Uncast literal 18446744073709551615 is treated as -1 !'); // readln; end.
Checking project dependencies... Compiling Project1.dproj (Debug, Win64) brcc32 command line for "Project1.vrc" c:\emb\radstudiorio\200\bin\cgrc.exe -c65001 Project1.vrc -foProject1.res dcc64 command line for "Project1.dpr" c:\emb\radstudiorio\200\bin\dcc64.exe -$O- -$W+ --no-config -M -Q -TX.exe -AGenerics.Collections=System.Generics.Collections; Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG -E.\Win64\Debug -Ic:\emb\radstudiorio\200\lib\Win64\debug;C:\EMB\FirePower\source\Win64\Debug;c:\emb\radstudiorio\200\lib\Win64\release; C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports; C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win64\Debug; C:\EMB\FastReport\LIBD26x64 -LEC:\Users\Public\Documents\Embarcadero\Studio\20.0\Bpl\Win64 -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; System;Xml;Data;Datasnap;Web;Soap; -Oc:\emb\radstudiorio\200\lib\Win64\release;C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports; c:\emb\radstudiorio\200\Imports;C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64;c:\emb\radstudiorio\200\include; C:\EMB\FirePower\source\Win64\Debug;C:\EMB\FastReport\LIBD26x64 -Rc:\emb\radstudiorio\200\lib\Win64\release; C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports; C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win64\Debug; C:\EMB\FastReport\LIBD26x64 -Uc:\emb\radstudiorio\200\lib\Win64\debug;C:\EMB\FirePower\source\Win64\Debug;c:\emb\radstudiorio\200\lib\Win64\release; C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports; C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win64\Debug; C:\EMB\FastReport\LIBD26x64 -CC -V -VN -VR -NBC:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64 -NHC:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win64 -NO.\Win64\Debug Project1.dpr [dcc64 Warning] Project1.dpr(35): W1012 Constant expression violates subrange bounds [dcc64 Warning] Project1.dpr(36): W1012 Constant expression violates subrange bounds Success Elapsed time: 00:00:00.3
program Project1; {$APPTYPE CONSOLE} {$R *.res} {$IFDEF FPC} {$MODE Delphi} {$ENDIF} uses SysUtils; {$IFNDEF FPC} type QWord = UInt64; {$ENDIF} var qw: QWord; begin qw := $FFFFFFFFFFFFFFFF; Writeln('Write variable and constant literal:'); Writeln(qw, ' **** ', qw); Writeln($FFFFFFFFFFFFFFFF, ' **** ', $FFFFFFFFFFFFFFFF); Writeln(18446744073709551615, ' **** ', 18446744073709551615); Writeln; Writeln('Write with IntToStr:'); Writeln(IntToStr(qw),' **** ', qw); // {$R-} // ignoring range checking = compile! Writeln(IntToStr($FFFFFFFFFFFFFFFF),' **** ', $FFFFFFFFFFFFFFFF); Writeln(IntToStr(18446744073709551615),' **** ', 18446744073709551615); {$R+} // Writeln; if qw < 0 then Writeln('Uncast unsigned QWORD is less than 0!?!'); if QWord($FFFFFFFFFFFFFFFF) < 0 then Writeln('Cast unsigned QWORD is less than 0!?!'); if $FFFFFFFFFFFFFFFF < 0 then Writeln('Uncast literal $FFFFFFFFFFFFFFFF is treated as -1 !'); if 18446744073709551615 < 0 then Writeln('Uncast literal 18446744073709551615 is treated as -1 !'); // readln; end.
Checking project dependencies... Compiling Project1.dproj (Debug, Win64) brcc32 command line for "Project1.vrc" c:\emb\radstudio210\bin\cgrc.exe -c65001 Project1.vrc -foProject1.res dcc64 command line for "Project1.dpr" c:\emb\radstudio210\bin\dcc64.exe -$O- -$W+ --no-config -M -Q -TX.exe -AGenerics.Collections=System.Generics.Collections; Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG -E.\Win64\Debug -Ic:\emb\radstudio210\lib\Win64\debug;C:\Emb\QuickReport\src\Win64\Debug;C:\Emb\QuickReport\Win64\Debug; c:\emb\radstudio210\lib\Win64\release;C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports;c:\emb\radstudio210\Imports; C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp\Win64;c:\emb\radstudio210\include;C:\Emb\QuickReport\src -LEC:\Users\Public\Documents\Embarcadero\Studio\21.0\Bpl\Win64 -LNC:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp\Win64 -NU.\Win64\Debug -NSWinapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;System;Xml;Data;Datasnap;Web;Soap; -Oc:\emb\radstudio210\lib\Win64\release; C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports;c:\emb\radstudio210\Imports; C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp\Win64;c:\emb\radstudio210\include;C:\Emb\QuickReport\src -Rc:\emb\radstudio210\lib\Win64\release;C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports;c:\emb\radstudio210\Imports; C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp\Win64;c:\emb\radstudio210\include;C:\Emb\QuickReport\src -Uc:\emb\radstudio210\lib\Win64\debug; C:\Emb\QuickReport\src\Win64\Debug;C:\Emb\QuickReport\Win64\Debug;c:\emb\radstudio210\lib\Win64\release; C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports;c:\emb\radstudio210\Imports; C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp\Win64;c:\emb\radstudio210\include;C:\Emb\QuickReport\src -CC -V -VN -VR -NBC:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp\Win64 -NHC:\Users\Public\Documents\Embarcadero\Studio\21.0\hpp\Win64 -NO.\Win64\Debug Project1.dpr [dcc64 Warning] Project1.dpr(35): W1012 Constant expression violates subrange bounds [dcc64 Warning] Project1.dpr(36): W1012 Constant expression violates subrange bounds Success Elapsed time: 00:00:00.2
program Project1; {$APPTYPE CONSOLE} {$R *.res} {$IFDEF FPC} {$MODE Delphi} {$ENDIF} uses SysUtils; {$IFNDEF FPC} type QWord = UInt64; {$ENDIF} var qw: QWord; begin qw := $FFFFFFFFFFFFFFFF; Writeln('Write variable and constant literal:'); Writeln(qw, ' **** ', qw); Writeln($FFFFFFFFFFFFFFFF, ' **** ', $FFFFFFFFFFFFFFFF); Writeln(18446744073709551615, ' **** ', 18446744073709551615); Writeln; Writeln('Write with IntToStr:'); Writeln(IntToStr(qw),' **** ', qw); // {$R-} // ignoring range checking = compile! Writeln(IntToStr($FFFFFFFFFFFFFFFF),' **** ', $FFFFFFFFFFFFFFFF); Writeln(IntToStr(18446744073709551615),' **** ', 18446744073709551615); {$R+} // Writeln; if qw < 0 then Writeln('Uncast unsigned QWORD is less than 0!?!'); if QWord($FFFFFFFFFFFFFFFF) < 0 then Writeln('Cast unsigned QWORD is less than 0!?!'); if $FFFFFFFFFFFFFFFF < 0 then Writeln('Uncast literal $FFFFFFFFFFFFFFFF is treated as -1 !'); if 18446744073709551615 < 0 then Writeln('Uncast literal 18446744073709551615 is treated as -1 !'); // readln; end.
function IntToStr(Value: Integer): string; begin if Value < 0 then Result := _IntToStr32(-Value, True) else Result := _IntToStr32(Value, False); end;
function IntToStr(Value: Int64): string; begin if Value < 0 then Result := _IntToStr64(-Value, True) else Result := _IntToStr64(Value, False); end;
function UIntToStr(Value: Cardinal): string; begin Result := _IntToStr32(Value, False); end;
function UIntToStr(Value: UInt64): string; begin Result := _IntToStr64(Value, False); end;
***********************
function _IntToStr32(Value: Cardinal; Negative: Boolean): string; var I, J, K : Cardinal; Digits : Integer; P : PChar; NewLen : Integer; begin I := Value; if I >= 10000 then if I >= 1000000 then if I >= 100000000 then Digits := 9 + Ord(I >= 1000000000) else Digits := 7 + Ord(I >= 10000000) else Digits := 5 + Ord(I >= 100000) else if I >= 100 then Digits := 3 + Ord(I >= 1000) else Digits := 1 + Ord(I >= 10); NewLen := Digits + Ord(Negative); SetLength(Result, NewLen); P := PChar(Result); P^ := '-'; Inc(P, Ord(Negative)); if Digits > 2 then repeat J := I div 100; {Dividend div 100} K := J * 100; K := I - K; {Dividend mod 100} I := J; {Next Dividend} Dec(Digits, 2); PDWord(P + Digits)^ := DWord(TwoDigitLookup[K]); until Digits <= 2; if Digits = 2 then PDWord(P+ Digits-2)^ := DWord(TwoDigitLookup[I]) else PChar(P)^ := Char(I or ord('0')); end;
function _IntToStr64(Value: UInt64; Negative: Boolean): string; var I64, J64, K64 : UInt64; I32, J32, K32, L32 : Cardinal; Digits : Byte; P : PChar; NewLen : Integer; begin {Within Integer Range - Use Faster Integer Version} if (Negative and (Value <= High(Integer))) or (not Negative and (Value <= High(Cardinal))) then Exit(_IntToStr32(Value, Negative)); I64 := Value; if I64 >= 100000000000000 then if I64 >= 10000000000000000 then if I64 >= 1000000000000000000 then if I64 >= 10000000000000000000 then Digits := 20 else Digits := 19 else Digits := 17 + Ord(I64 >= 100000000000000000) else Digits := 15 + Ord(I64 >= 1000000000000000) else if I64 >= 1000000000000 then Digits := 13 + Ord(I64 >= 10000000000000) else if I64 >= 10000000000 then Digits := 11 + Ord(I64 >= 100000000000) else Digits := 10; NewLen := Digits + Ord(Negative); SetLength(Result, NewLen); P := PChar(Result); P^ := '-'; Inc(P, Ord(Negative)); if Digits = 20 then begin P^ := '1'; Inc(P); Dec(I64, 10000000000000000000); Dec(Digits); end; if Digits > 17 then begin {18 or 19 Digits} if Digits = 19 then begin P^ := '0'; while I64 >= 1000000000000000000 do begin Dec(I64, 1000000000000000000); Inc(P^); end; Inc(P); end; P^ := '0'; while I64 >= 100000000000000000 do begin Dec(I64, 100000000000000000); Inc(P^); end; Inc(P); Digits := 17; end; J64 := I64 div 100000000; K64 := I64 - (J64 * 100000000); {Remainder = 0..99999999} I32 := K64; J32 := I32 div 100; K32 := J32 * 100; K32 := I32 - K32; PDWord(P + Digits - 2)^ := DWord(TwoDigitLookup[K32]); I32 := J32 div 100; L32 := I32 * 100; L32 := J32 - L32; PDWord(P + Digits - 4)^ := DWord(TwoDigitLookup[L32]); J32 := I32 div 100; K32 := J32 * 100; K32 := I32 - K32; PDWord(P + Digits - 6)^ := DWord(TwoDigitLookup[K32]); PDWord(P + Digits - 8 )^ := DWord(TwoDigitLookup[J32]); Dec(Digits, 8 ); I32 := J64; {Dividend now Fits within Integer - Use Faster Version} if Digits > 2 then repeat J32 := I32 div 100; K32 := J32 * 100; K32 := I32 - K32; I32 := J32; Dec(Digits, 2); PDWord(P + Digits)^ := DWord(TwoDigitLookup[K32]); until Digits <= 2; if Digits = 2 then PDWord(P + Digits-2)^ := DWord(TwoDigitLookup[I32]) else P^ := Char(I32 or ord('0')); end;
Try
procedure something (a:int64;b:uint64); begin writeln(a+b); end;
And then for varying (small and large, negative and positive) a and b.
And testing $FFFFFFFFFFFFFFFF with VAL() of course
program Project1; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; procedure something(a: int64; b: uint64); begin writeln(a + b); end; begin try writeln(''); something(1, 1); something(int64.MaxValue, uint64.MaxValue); readln; except on E: Exception do writeln(E.ClassName, ': ', E.Message); end; end.
Try
And testing $FFFFFFFFFFFFFFFF with VAL() of course
Converts a string that represents an integer (decimal or hex notation) into a number. In Delphi code, Val converts the string value S to its numeric representation, as if it were read from a text file with Read. Both 0$1234 and 0x1234 are the hexadecimal notations supported. S is a string-type expression; it must be a sequence of characters that form a signed real number, such as "1", "-2" or "+3". Other than the optional sign at the beginning, all characters must be digits; decimal or thousands separators are not supported. V is an integer-type or real-type variable. If V is an integer-type variable, S must form a whole number. Code is a variable of type Integer. If the string is invalid, the index of the offending character is stored in Code; otherwise, Code is set to zero. For a null-terminated string, the error position returned in Code is one larger than the actual zero-based index of the character in error.
program Project2; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; var s : string; V : UInt64; // my choice Code: Integer; // should be Interger begin try writeln(''); writeln(''); s := '$FFFFFFFFFFFFFFFF'; // should be Int64 type val(s, V, Code); writeln('s := $FFFFFFFFFFFFFFFF - val(s, V, Code);'); writeln(''); writeln(V); readln; except on E: Exception do writeln(E.ClassName, ': ', E.Message); end; end.
program Project2; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; var s : string; V : UInt64; // my choice Code: Integer; // should be Interger begin try writeln(''); writeln(''); s := '$FFFFFFFFFFFFFFFF'; // should be Int64 type val(s, V, Code); writeln('s := $FFFFFFFFFFFFFFFF - val(s, V, Code);'); writeln(''); writeln(V); readln; except on E: Exception do writeln(E.ClassName, ': ', E.Message); end; end.
Delphi val( '$ffffffffffffffff', intVar, code)
just behaves like overloaded functions:
1) If intVar has type int64, then intVar becomes -1,
because val() implements implicit typecast from uint64 input to int64.