Lazarus

Programming => General => Topic started by: julkas on August 06, 2020, 06:14:05 pm

Title: Implicit converison, literals and QWORD variable warning
Post by: julkas on August 06, 2020, 06:14:05 pm
Same code on Windows 10 64bit and FPC, Delphi output -
Code: Pascal  [Select][+][-]
  1. program consta;
  2. {$IFDEF FPC}
  3. {$MODE Delphi}
  4. {$ENDIF}
  5. uses SysUtils;
  6.  
  7. const
  8.   c64_1         = $FFFFFFFFFFFFFFFF;
  9.   c64_2  = UInt64($FFFFFFFFFFFFFFFF);
  10.   c64_3: UInt64 = $FFFFFFFFFFFFFFFF;
  11.  
  12. var
  13.   v64: UInt64 = c64_1;
  14.  
  15. begin
  16.   WriteLn(Format('c64_1: %x - %u', [c64_1, c64_1]));   
  17.   if c64_1 < 0 then
  18.     WriteLn('c64_1 < 0');
  19.   WriteLn(Format('c64_2: %x - %u', [c64_2, c64_2]));   
  20.   if c64_2 < 0 then
  21.     WriteLn('c64_2 < 0');
  22.   WriteLn(Format('c64_3: %x - %u', [c64_3, c64_3]));   
  23.   if c64_3 < 0 then
  24.     WriteLn('c64_3 < 0');      
  25.  
  26.   WriteLn(Format('v64  : %x - %u', [v64, v64]));       
  27.   if v64 < 0 then
  28.     WriteLn('v64 < 0');
  29.        
  30. end.
  31.  

FPC output -
Code: Bash  [Select][+][-]
  1. $ fpc -B consta.pas
  2. Free Pascal Compiler version 3.0.4 [2020/04/11] for x86_64
  3. Copyright (c) 1993-2017 by Florian Klaempfl and others
  4. Target OS: Win64 for x64
  5. Compiling consta.pas
  6. consta.pas(10,36) Warning: range check error while evaluating constants (-1 must be between 0 and 18446744073709551615)
  7. consta.pas(13,22) Warning: range check error while evaluating constants (-1 must be between 0 and 18446744073709551615)
  8. consta.pas(21,5) Warning: unreachable code
  9. consta.pas(23,12) Warning: Comparison might be always false due to range of constant and expression
  10. consta.pas(24,5) Warning: unreachable code
  11. consta.pas(27,10) Warning: Comparison might be always false due to range of constant and expression
  12. consta.pas(28,5) Warning: unreachable code
  13. Linking consta.exe
  14. 29 lines compiled, 0.2 sec, 71488 bytes code, 4932 bytes data
  15. 7 warning(s) issued
  16.  
  17. $ ./consta.exe
  18. c64_1: FFFFFFFF - 4294967295
  19. c64_1 < 0
  20. c64_2: FFFFFFFFFFFFFFFF - 18446744073709551615
  21. c64_3: FFFFFFFFFFFFFFFF - 18446744073709551615
  22. v64  : FFFFFFFFFFFFFFFF - 18446744073709551615
  23.  

Delphi 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(30)
  5. 31 lines, 0.09 seconds, 175348 bytes code, 63152 bytes data.
  6.  
  7. $ ./consta.exe
  8. c64_1: FFFFFFFFFFFFFFFF - 18446744073709551615
  9. c64_2: FFFFFFFFFFFFFFFF - 18446744073709551615
  10. c64_3: FFFFFFFFFFFFFFFF - 18446744073709551615
  11. v64  : FFFFFFFFFFFFFFFF - 18446744073709551615
  12.  

Title: Re: Implicit converison, literals and QWORD variable warning
Post by: Remy Lebeau on August 06, 2020, 06:17:29 pm
(posting a new thread since the original thread (https://forum.lazarus.freepascal.org/index.php/topic,50896.0.html) is locked)

The Rio is the current version of Delphi, AFAIK

Actually, 10.4 Sydney was released a few months ago.  10.3 Rio was the previous version, released in late 2018.

Can anyone who have Rio confirm all this?

I have posted the question to the Delphi forum:

FreePascal compatibility - how is this kind of code compiled in Delphi 10.3 Rio or 10.4 Sydney? (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)
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: Thaddy on August 06, 2020, 06:24:46 pm
Interesting.
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?
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....
On the CPU level this is impossible. It is either signed or unsigned.
Whereas a typed const has the required capability.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: marcov on August 06, 2020, 06:59:17 pm
(I merged some follow ups to the locked thread (I don't know who locked it).

Julkas: read the thread referenced in the url in Remy's post.

Remy: thanks. Discovery is the key. Test both 32-bit and 64-bit.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: FPK on August 06, 2020, 07:21:13 pm
The question is simple: is $FFFFFFFFFFFFFFFF a valid int64 or not? For FPC we decided, yes. For Delphi apparently not, at least not after when they introduced the 64 bit unsigned type.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: julkas on August 06, 2020, 07:34:40 pm
Output on WSL -
Code: Bash  [Select][+][-]
  1. $ fpc -B consta.pas
  2. Free Pascal Compiler version 3.2.0 [2020/06/14] for x86_64
  3. Copyright (c) 1993-2020 by Florian Klaempfl and others
  4. Target OS: Linux for x86-64
  5. Compiling consta.pas
  6. consta.pas(10,36) Warning: range check error while evaluating constants (-1 must be between 0 and 18446744073709551615)
  7. consta.pas(13,22) Warning: range check error while evaluating constants (-1 must be between 0 and 18446744073709551615)
  8. consta.pas(21,5) Warning: unreachable code
  9. consta.pas(23,12) Warning: Comparison might be always false due to range of constant and expression
  10. consta.pas(24,5) Warning: unreachable code
  11. consta.pas(27,10) Warning: Comparison might be always false due to range of constant and expression
  12. consta.pas(28,5) Warning: unreachable code
  13. Linking consta
  14. 29 lines compiled, 1.5 sec
  15. 7 warning(s) issued
  16.  
  17. $ ./consta
  18. c64_1: FFFFFFFF - 4294967295
  19. c64_1 < 0
  20. c64_2: FFFFFFFFFFFFFFFF - 18446744073709551615
  21. c64_3: FFFFFFFFFFFFFFFF - 18446744073709551615
  22. v64  : FFFFFFFFFFFFFFFF - 18446744073709551615
  23.  
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: ASerge on August 06, 2020, 09:05:48 pm
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?
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....
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.
Example:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$MODE OBJFPC}
  3.  
  4. procedure PrintTypeForNumber(const S: AnsiString);
  5. type
  6.   TRange = record
  7.     Min, Max: Int64;
  8.     TypeName: AnsiString;
  9.   end;
  10. const
  11.   CRanges: array[0..5] of TRange = (
  12.     (Min: Low(Int8); Max: High(Int8); TypeName: 'ShortInt'),
  13.     (Min: Low(UInt8); Max: High(UInt8); TypeName: 'Byte'),
  14.     (Min: Low(Int16); Max: High(Int16); TypeName: 'SmallInt'),
  15.     (Min: Low(UInt16); Max: High(UInt16); TypeName: 'Word'),
  16.     (Min: Low(Int32); Max: High(Int32); TypeName: 'Integer'),
  17.     (Min: Low(UInt32); Max: High(UInt32); TypeName: 'Cardinal'));
  18. var
  19.   RInt64: Int64;
  20.   RQWord: QWord;
  21.   Err: Integer;
  22.   iRange: TRange;
  23. begin
  24.   Val(S, RQWord, Err);
  25.   if (Err = 0) and (RQWord > High(Int64)) then
  26.   begin
  27.     Writeln(S, ' is QWord type');
  28.     Exit;
  29.   end;
  30.   Val(S, RInt64, Err);
  31.   if Err <> 0 then
  32.   begin
  33.     Writeln(S, ' is not integer value');
  34.     Exit;
  35.   end;
  36.   for iRange in CRanges do
  37.     if (RInt64 >= iRange.Min) and (RInt64 <= iRange.Max) then
  38.     begin
  39.       Writeln(S, ' is ', iRange.TypeName, ' type');
  40.       Exit;
  41.     end;
  42.   Writeln(S, ' is Int64 type');
  43. end;
  44.  
  45. var
  46.   S: AnsiString;
  47. begin
  48.   repeat
  49.     Write('Enter integer number (empty for exit):');
  50.     Readln(S);
  51.     if S = '' then
  52.       Break;
  53.     PrintTypeForNumber(S);
  54.   until False;
  55. end.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: julkas on August 07, 2020, 08:10:16 am
About C++ integer literals - https://en.cppreference.com/w/cpp/language/integer_literal
From Notes -
There are no negative integer constants.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: marcov on August 07, 2020, 10:07:40 am
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.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: process_1 on August 07, 2020, 11:12:22 am
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 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:

Code: C  [Select][+][-]
  1.  
  2. #include <iostream>
  3.  
  4. using namespace std;
  5.  
  6. int main ()
  7. {
  8.   if (0xFFFFFFFFFFFFFFFF < 0)
  9.     cout << "0xFFFFFFFFFFFFFFFF is less than 0!\n";
  10.   else
  11.     cout << "0xFFFFFFFFFFFFFFFF is unsigned!\n";        // Always executable
  12.  
  13.  
  14.   if (0xFFFFFFFFFFFFFFFFLL < 0)
  15.     cout << "0xFFFFFFFFFFFFFFFFLL is less than 0!\n";
  16.   else
  17.     cout << "0xFFFFFFFFFFFFFFFFLL is unsigned!\n";      // Always executable
  18.  
  19.  
  20.   if (0xFFFFFFFFFFFFFFFFULL < 0)
  21.     cout << "0xFFFFFFFFFFFFFFFFULL is less than 0!\n";
  22.   else
  23.     cout << "0xFFFFFFFFFFFFFFFFULL is unsigned!\n";     // Always executable
  24.  
  25.   if (0xFFFFL < 0)
  26.     cout << "0xFFFFFL is less than 0!\n";
  27.   else
  28.     cout << "0xFFFFFL is unsigned!\n";  // Always executable
  29.  
  30.   return 0;
  31. }
  32.  

If you do not have any C++ compiler, there is online compiler, then choose any listed C++ standard of interest:

https://www.onlinegdb.com/online_c++_compiler
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: marcov on August 07, 2020, 11:44:48 am
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.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: process_1 on August 07, 2020, 12:10:32 pm

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.

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.

Quote
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 papers for C++ standards are here https://isocpp.org
For instance, C++20 standard is here: https://isocpp.org/files/papers/N4860.pdf

GNU C/C++ have to follow all these rules for specific standard, before they claims it is fully supported, is it?
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: Warfley on August 07, 2020, 01:19:07 pm
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:

This behaviour also is the only one that makes sense, because neither C nor C++ (before c++20) defined how signed numbers are implemented, which means overflow is undefined behaviour. A hex constant is just another way of writing a number. So you give the compiler a huge positive number which can not be converted to a signed number, because this would require overflow to be defined.
Now the compiler looks at the if cases and sees a comparison between a positive number and 0, and this is a trivial tautology. A positive number is never smaller than 0. So the compiler simply removes the if's completely, which can be seen when decompiling your project again:
Code: C  [Select][+][-]
  1. undefined8 main(void)
  2. {
  3.   operator<<<std--char_traits<char>>
  4.             ((basic_ostream *)__TMC_END__,"0xFFFFFFFFFFFFFFFF is unsigned!\n");
  5.   operator<<<std--char_traits<char>>
  6.             ((basic_ostream *)__TMC_END__,"0xFFFFFFFFFFFFFFFFLL is unsigned!\n");
  7.   operator<<<std--char_traits<char>>
  8.             ((basic_ostream *)__TMC_END__,"0xFFFFFFFFFFFFFFFFULL is unsigned!\n");
  9.   operator<<<std--char_traits<char>>((basic_ostream *)__TMC_END__,"0xFFFFFL is unsigned!\n");
  10.   return 0;
  11. }

You simply can't use positive numbers to represent negative numbers in C and C++ (at least until C++20). The correct and portable (between any size and signedness) way to have a bitmask where every bit is 1 is to write ~0

Note that also bitshifts which cross the negative positive boundary are undefined behaviour:
Code: C  [Select][+][-]
  1. int x = 1;
  2. x << 31; // undefined behaviour because the resulting number would be larger than 2^31-1
  3. x = -1;
  4. x >> 5; // undefined behaviour because right shift on negative number
  5.  

So writing large hex constants as bit masks for signed types, or shifting to the sign bit to create bit masks is simply broken C and C++ code
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: marcov on August 07, 2020, 02:51:54 pm
Just post an example what you want to accomplish. Type promotion rules applies here without an issue.

As said, literals are per definition signed. Even if you change the $FFFFFFFF etc to unsigned, then still the 0 is signed.

Quote
Problem in FPC, however, is arbitrary rule for unwanted integer literals implicit conversion, as already pointed.

Anything relating to the highest unsigned type is arbitrary, as I have explained it to be a hack since there is no larger signed type for it. But solutions must be limited to the place where the literal is parsed, and not fan out to every place where a literal might be used to try to preserve the expression as unsigned.

That is not fixing a corner case, but changing the language so far that it might as well be a new one.

And that brings us back to how Delphi does it. All this talk about C/C++ is utterly useless.

Quote
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 papers for C++ standards are here https://isocpp.org
For instance, C++20 standard is here: https://isocpp.org/files/papers/N4860.pdf

GNU C/C++ have to follow all these rules for specific standard, before they claims it is fully supported, is it?
[/quote]

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_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.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: process_1 on August 07, 2020, 03:12:31 pm
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. But even to reinvent wheel properly, 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.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: Warfley on August 07, 2020, 03:14:44 pm
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_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.
In 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

Examples overflow (and therefore the conversion of unsigned to singed numbers) is undefined, therefore a big no-no as the behaviour can change on any compiler (version), optimization level or even by the time of day, you can't know. So if you try to put $FFFFFFFF into an 32 bit signed int and expect it to be -1, you just wrote a broken program

The bitshift of negative signed integers from my example above is implementation specific, meaning it is well documented but does not conform to the standard, therefore you can use it as long as you stick to the same compiler. So if you rely on -1 >> 31 == -1, this is completely fine as long as you stick to gcc
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: marcov on August 07, 2020, 03:47:00 pm
Yes, this because on some non two-complement machines actually enforcing any rule can require (many) extra instructions, which would be counter productive.

And yes, there are various gradations. In some cases standards give you a choice between options etc.

I never did much with the C language standard, but I do know K&R pretty well.  While I convert and wrap it all the time I haven't programmed much own code in C++, aside from said wrappers.  Let alone spelled out the standard.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: FPK on August 07, 2020, 06:03:15 pm
I do not get what's the fuzz about C here. Pascal is not C/C++. In FPC the rules are very simple: if a token is encountered which consists of digits (including A-F for hex), the compiler first tries to convert it to int64 as this is the largest ordinal type (qword is strictly speaking not an ordinal type in the pascal sense). If this conversion works (done by val), fine, continue with the constant being an int64. If this fails, qword is tried (also using val) and if everthings fails, the floats. As $ffffffffffffffff (2^64-1) is accepted by val as an int64, it is handled as an int64. That's it. Very simple. Very consistent.

Testing Byte, Shortint etc. separately makes no sense in pascal. This would be a random choice. That byte is one byte etc. in pascal is only an implementation detail strictly speaking.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: Warfley on August 07, 2020, 06:24:20 pm
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.

C is in that regard much simpler, because in C, if you supply a large number you get a large number and not a tiny negative number. Also in C you can even influence for small numbers how they shall be represented, like 0LL will be 64 bit all 0.
In pascal I more often than not Feel that I don't have much control other than using casts
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: marcov on August 07, 2020, 06:27:42 pm
All this talk about C/C++ is utterly useless.

No body force you to read, nor to reply.

Back to you. But putting C/C++ mindlessly on some pedestal is not constructive.

Quote
The benefit reading other standards is to learn how properly to handle problems in any compiler,

But you don't provide any tradeoff of the C++ parsing model. You take this very minute detail, and then point out to some standard based on a total alien parsing, constant declaration and import (between compilation units) model, and conclude that changing to that model is great because it fixes a corner case, and it is all there in the standard.

No practical information, nothing.

Quote
not to reinvent the wheel.

Please go to the C++ forums that are currently discussing modular support, and tell them not to reinvent the wheel because Pascal solved that 40 years ago, they just have to adopt Pascal's everything.

See how that is received.


Quote
it seems some Pandora's boxes are opened in the core of FPC.

And all that conclusion from just one warning.  And I assume without looking at the FPC source.

Quote
In this case consistency. But you constantly ignoring that, which is your problem and I do not really care about.

I've explained the consistency several times and you chose to ignore that.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: FPK on August 07, 2020, 06:28:34 pm
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.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: Warfley on August 07, 2020, 06:32:48 pm
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.

The whole point if this is easy or not is to someone who did not read the entire documentation of the compiler, who just wants to write a program.

In C that is easy, you supply a huge number, you get a huge number and not a tiny negative number.

Just imagine going into a bar and asking for a double shot vodka, but you get a single shot of water instead, and then getting told: "Well if you read the fine print on the last page of our cart it says that orders of double shots are converted to single shots of water"
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: process_1 on August 07, 2020, 06:36:55 pm
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?
Well ignore it freely, that is your choice.

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?
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: FPK on August 07, 2020, 06:53:36 pm
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

var
  i : int64;
  c : longint;
 
begin
  val('$ffffffffffffffff',i,c);
  if c=0 then
    writeln('ok');
end.


cannot be solved this way. 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.

I hope the people promoting changing this here are then as active as writing posts here when it is about to fix bugs caused by this change and helping people fix their broken code.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: process_1 on August 07, 2020, 07:02:30 pm

*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 "a lot of people" would place $ffffffffffffffff to int64 instead simply -1? This is nonsense for higher languages and I cannot imagine who would do that (I'm bloody professional senior programmer, BTW). Now we have uint64 as native type, thus implicity convert such literal to -1 is something have no sense at all!

Even so, for instance integer length depend on platform, right? Putting  $ffffffff to it assummng it is 32-bit signed type and actually -1 is not platform independent code, right?
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: nanobit on August 07, 2020, 07:05:35 pm
In the long run (hobbyists like me are patient enough to wait decades),
FPC might adopt the unsigned interpretation of all hexadecimal literals.
This would be a breaking change, but only literals having byte 7 (of 7..0) in range $80..$FF
change their meaning (to being positive) and programmers can prepare already:
Use typecasting which is required if literal byte 7 is in range $80..$FF:
Example: uint64( $FFFFFFFFFFFFFFFF) or  int64( $FFFFFFFFFFFFFFFF)

The current concept (int64) breaks the sign-consistency:
i128 := $FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;  // i128 negative
i128 := $FFFFFFFFFFFFFFFF;  // i128 negative
i128 := $FFFFFFFF;  // i128 positive
i128 := $FFFF;  // i128 positive
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: FPK on August 07, 2020, 07:18:21 pm

*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?

... because -1 is $ffffffff on 32 bit platforms?


Anyways, enough discussion, the behaviour can be changed by the following patch:

Code: Pascal  [Select][+][-]
  1. diff --git a/rtl/inc/sstrings.inc b/rtl/inc/sstrings.inc
  2. index 7d47640baa..e76920d7f6 100644
  3. --- a/rtl/inc/sstrings.inc
  4. +++ b/rtl/inc/sstrings.inc
  5. @@ -1170,10 +1170,10 @@ begin
  6.        exit;
  7.      end;
  8.    maxPrevValue := ValUInt(MaxUIntValue) div ValUInt(Base);
  9. -  if (base = 10) then
  10. -    maxNewValue := MaxSIntValue + ord(negative)
  11. -  else
  12. -    maxNewValue := MaxUIntValue;
  13. +//  if (base = 10) then
  14. +    maxNewValue := MaxSIntValue + ord(negative);
  15. +//  else
  16. +//    maxNewValue := MaxUIntValue;
  17.    while Code<=Length(s) do
  18.     begin
  19.       case s[Code] of
  20. @@ -1285,10 +1285,10 @@ end;
  21.          exit;
  22.        end;
  23.      maxprevvalue := maxqword div base;
  24. -    if (base = 10) then
  25. -      maxnewvalue := maxint64 + ord(negative)
  26. -    else
  27. -      maxnewvalue := maxqword;
  28. +//    if (base = 10) then
  29. +      maxnewvalue := maxint64 + ord(negative);
  30. +//    else
  31. +//      maxnewvalue := maxqword;
  32.  
  33.      while Code<=Length(s) do
  34.       begin
  35.  

I am waiting for patches fixing the resulting problems, then we will see how it turns out and we can continue to discuss.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: Remy Lebeau on August 07, 2020, 08:43:36 pm
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.

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
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: marcov on August 07, 2020, 09:15:39 pm
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?

Applying them out of context.

Quote
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.

So, why is it fundamental? As said (if you actually bothered to read the replies) it is a result of the base type system.

Quote
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?

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.

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.

Title: Re: Implicit converison, literals and QWORD variable warning
Post by: process_1 on August 07, 2020, 09:17:59 pm
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

Remy,

Thank you for publishing this on Embarcadero forum and to that user Emailx45 for testing.

Too bad there is no message list after compilation and console log after running in order to compare all in details.


Title: Re: Implicit converison, literals and QWORD variable warning
Post by: Warfley on August 07, 2020, 09:26:56 pm
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
Code: C  [Select][+][-]
  1. constexpr auto x = 0xFFFFFFFFFFFFFFFF;
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: process_1 on August 07, 2020, 09:35:39 pm
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 is introduced by Delphi and when with FPC as native type. AFAIK, that happens few years ago and as such is hardly "analyezed to death 20+ years ago" . I bet it was introduced in FPC without any deeper though about.

The prove for that are these ridicilous warnings and implicit conversion positive large literals to negative one. And that is not fundamental bug? Perhaps it is minor glitch, then?
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: marcov on August 07, 2020, 09:51:36 pm
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?

Same, but 32-bit case, before int64-on-32-bit introduction. As said, initially D3 was released with a 31-bit unsigned integer. (see e.g. http://www.ebob42.eu/delphi4/language.htm )

Even GCC derivate GNU Pascal did something similar for a while that makes clear the issues involved are not fanta, since these three (Delphi, FPC, GPC) are codebases independent of each other (see https://www.gnu-pascal.de/gpc/Cardinal.html)

Quote
Don't be theatrical,

I'm not. I name easy verifiable facts. For your convenience I added some links above.

Quote
please and write when uint64 in introduced by Delphi and when with FPC as native type.

I don't know about Delphi, I think XE2, since adding 64-bit triggered a major compiler revamp. FPC was earlier, 2.2 or 2.4.

Quote
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.

Bet based on what? I've already mentioned the cardinal->longword migration of Delphi in the early 2000s several times.

But yes, it was introduced while it was known to be flawed. The reasoning is that it would be better to directly translate structures (e.g. winapi) to it using the correct types, and increasing 64-bit activity made that come closer, and if you didn't mix types it would be ok. (e.g. a type that is a file offset).

Keep in mind that even e.g. 64-bit file offsets are signed, on both Unix and Windows.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: FPK on August 07, 2020, 10:00:28 pm
when with FPC as native type. AFAIK, that happens few years ago

Well, define few? 21 years is not few.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: FPK on August 07, 2020, 10:09:34 pm
Well, define few? 21 years is not few.

And for the record: Int64/QWord were added 1998/1999 (finally enabled 1st July 1999) to be able to add Alpha and iA64 support to FPC which was at least a good preparation for the x86-64 port in 2003/2004.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: winni on August 07, 2020, 10:31:55 pm
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}

Code: Pascal  [Select][+][-]
  1. const  nonsense  = $FFFFFFFFF;   // 9 x F
  2. var I : Int64;
  3.      pw : single;
  4.      s: string;
  5. begin
  6. I := nonsense;
  7. pw := log2(I);
  8. showMessage (FloatToStr(pw));
  9. s := intToStr(nonsense);
  10. showMessage (s);                
  11. end;
  12.  
  13.  
Bug report?

Winni

PS No error message from the compiler or at runtime.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: PascalDragon on August 07, 2020, 11:21:03 pm
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.

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.

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}

Code: Pascal  [Select][+][-]
  1. const  nonsense  = $FFFFFFFFF;   // 9 x F
  2. var I : Int64;
  3.      pw : single;
  4.      s: string;
  5. begin
  6. I := nonsense;
  7. pw := log2(I);
  8. showMessage (FloatToStr(pw));
  9. s := intToStr(nonsense);
  10. showMessage (s);                
  11. end;
  12.  
  13.  
Bug report?

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.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: winni on August 07, 2020, 11:59:18 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.

Winni

Title: Re: Implicit converison, literals and QWORD variable warning
Post by: marcov on August 08, 2020, 12:14:17 am

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 !!!!)

$F means deceimal 15,  One hex digit is thus 4-bit. The last time I counted 9*4=36.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: Warfley on August 08, 2020, 12:37:58 am
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.

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
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: emailx45 on August 08, 2020, 05:05:32 am
hello people,

Im new here!

I have seen that the problem with UInt64 value = -1 is not problem only in Delphi (OP), but on fault of one type for "unsigned" for a big value like these.

I did the test in "online" calc on "https://calc.penjee.com/" (that certally is not build in Delphi or Larazus) and the resulted to FFFF.FFFF.FFFF.FFFF is -1, but only if the calculate is in 64bits signed, but if change to "unsigned" or  if you change to 128bits, então, the value will be 2^64-1 (18 qui.....) as expected.


more test mine here 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

If we have a UInt128 or more, the problem would be solved... for while!

sorry if im wrong  :-[
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: process_1 on August 08, 2020, 06:38:41 am
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

Indeed, this is hilarious! And my point exactly that what we talking about is nonsense in higher languages!

How many times is necessary to write that white is not black and vice verse?
How many times is necessary to write that $FFFFFFFFFFFFFFFF is constant literal and positive number 2^64-1 or 18446744073709551615, not -1, regardless the platform?

How many times is necessary to write that this code is dubious?
Code: Pascal  [Select][+][-]
  1.   if $FFFFFFFFFFFFFFFF < 0 then
  2.     writeln('Uncast literal $FFFFFFFFFFFFFFFF is treated as -1 !'); // Always executable!
  3.  
  4.  


Title: Re: Implicit converison, literals and QWORD variable warning
Post by: process_1 on August 08, 2020, 06:53:42 am
hello people,
...

Hello and welcome!

Thank you for your testing once again.

Can you please compile and run this on Delphi, copy and post here all compiler's messages after compilation and as well execution results?

Code: Pascal  [Select][+][-]
  1. var
  2.   qw: QWord;
  3. begin
  4.  
  5.   qw := $FFFFFFFFFFFFFFFF;
  6.  
  7.   Writeln('Write variable and constant literal');
  8.  
  9.   Writeln(qw);
  10.   Writeln($FFFFFFFFFFFFFFFF);
  11.  
  12.   Writeln;
  13.   Writeln('Write with IntToStr:');
  14.  
  15.   Writeln(IntToStr(qw));
  16.   Writeln(IntToStr($FFFFFFFFFFFFFFFF));
  17.  
  18.   if qw < 0 then
  19.     Writeln('Uncast unsigned QWORD is less than 0!?!');
  20.  
  21.   if qword($FFFFFFFFFFFFFFFF) < 0 then
  22.     Writeln('Cast unsigned QWORD is less than 0!?!');
  23.  
  24.   if $FFFFFFFFFFFFFFFF < 0 then
  25.     Writeln('Uncast literal $FFFFFFFFFFFFFFFF is treated as -1 !');    
  26.    
  27. end.
  28.  

Thank you in advance.

EDIT: Added code to write integers directly, by side with IntToStr().
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: julkas on August 08, 2020, 08:52:38 am
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.      
  14.       Writeln(IntToStr(qw));
  15.       Writeln(IntToStr($FFFFFFFFFFFFFFFF));
  16.      
  17.       if qw < 0 then
  18.         Writeln('Uncast unsigned QWORD is less than 0!?!');
  19.      
  20.       if qword($FFFFFFFFFFFFFFFF) < 0 then
  21.         Writeln('Cast unsigned QWORD is less than 0!?!');
  22.      
  23.       if $FFFFFFFFFFFFFFFF < 0 then
  24.         Writeln('Uncast literal $FFFFFFFFFFFFFFFF is treated as -1 !');    
  25.        
  26.     end.
  27.  
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(15) Warning: W1012 Constant expression violates subrange bounds
  5. consta.pas(27)
  6. 28 lines, 0.08 seconds, 174868 bytes code, 63136 bytes data.
  7.  
  8. $ ./consta.exe
  9. -1
  10. -1
  11.  
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: process_1 on August 08, 2020, 09:02:22 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.  
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: julkas 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.  
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: process_1 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
  11. Linking test
  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.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: ASerge 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);
  41.   Readln;
  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
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: PascalDragon 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 (https://www.freepascal.org/docs-html/current/ref/refsu4.html#x26-250003.1.1):

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.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: ASerge 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.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: process_1 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.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: nanobit 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);
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: Warfley on August 08, 2020, 08:53:15 pm
It is documented (https://www.freepascal.org/docs-html/current/ref/refsu4.html#x26-250003.1.1):

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
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: jamie 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.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: marcov 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.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: emailx45 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.   //
  36.   readln;
  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
  6.   -E.\Win32\Debug -Ic:\emb\radstudiorio\200\lib\Win32\debug;C:\EMB\FirePower\source\Win32\Debug;c:\emb\radstudiorio\200\lib\Win32\release;
  7.   C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports;
  8.   C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26
  9.   -LEC:\Users\Public\Documents\Embarcadero\Studio\20.0\Bpl -LNC:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp -NU.\Win32\Debug -NSWinapi;
  10.   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;
  11.   C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports;
  12.   C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26
  13.   -Rc:\emb\radstudiorio\200\lib\Win32\release;C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports;
  14.   C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26
  15.   -Uc:\emb\radstudiorio\200\lib\Win32\debug;C:\EMB\FirePower\source\Win32\Debug;c:\emb\radstudiorio\200\lib\Win32\release;
  16.   C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports;
  17.   C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26
  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.  
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: emailx45 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
  6.   -E.\Win32\Debug -Ic:\emb\radstudiorio\200\lib\Win32\debug;C:\EMB\FirePower\source\Win32\Debug;c:\emb\radstudiorio\200\lib\Win32\release;
  7.   C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports;
  8.   C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26
  9.   -LEC:\Users\Public\Documents\Embarcadero\Studio\20.0\Bpl -LNC:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp -NU.\Win32\Debug -NSWinapi;
  10.   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;
  11.   C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports;
  12.   C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26
  13.   -Rc:\emb\radstudiorio\200\lib\Win32\release;C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports;
  14.   C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26
  15.   -Uc:\emb\radstudiorio\200\lib\Win32\debug;C:\EMB\FirePower\source\Win32\Debug;c:\emb\radstudiorio\200\lib\Win32\release;
  16.   C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports;
  17.   C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win32\Debug;C:\EMB\FastReport\LIBD26
  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.   //
  53.   readln;
  54.  
  55. end.
  56.  

RAD 10.4 Sydney

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
  8.   -E.\Win32\Debug -Ic:\emb\radstudio210\lib\Win32\debug;C:\Emb\QuickReport\Win32\Debug;c:\emb\radstudio210\lib\Win32\release;
  9.   C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports;c:\emb\radstudio210\Imports;C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp;
  10.   c:\emb\radstudio210\include;C:\Emb\QuickReport\src -LEC:\Users\Public\Documents\Embarcadero\Studio\21.0\Bpl
  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;
  12.   System;Xml;Data;Datasnap;Web;Soap; -Oc:\emb\radstudio210\lib\Win32\release;C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports;
  13.   c:\emb\radstudio210\Imports;C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp;c:\emb\radstudio210\include;C:\Emb\QuickReport\src
  14.   -Rc:\emb\radstudio210\lib\Win32\release;C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports;c:\emb\radstudio210\Imports;
  15.   C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp;c:\emb\radstudio210\include;C:\Emb\QuickReport\src -Uc:\emb\radstudio210\lib\Win32\debug;
  16.   C:\Emb\QuickReport\Win32\Debug;c:\emb\radstudio210\lib\Win32\release;C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports;
  17.   c:\emb\radstudio210\Imports;C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp;c:\emb\radstudio210\include;C:\Emb\QuickReport\src -CC -V -VN
  18.   -NBC:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp -NHC:\Users\Public\Documents\Embarcadero\Studio\21.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: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.   //
  53.   readln;
  54.  
  55. end.
  56.  

Title: Re: Implicit converison, literals and QWORD variable warning
Post by: emailx45 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
  8.   -E.\Win64\Debug -Ic:\emb\radstudiorio\200\lib\Win64\debug;C:\EMB\FirePower\source\Win64\Debug;c:\emb\radstudiorio\200\lib\Win64\release;
  9.   C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports;
  10.   C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win64\Debug;
  11.   C:\EMB\FastReport\LIBD26x64 -LEC:\Users\Public\Documents\Embarcadero\Studio\20.0\Bpl\Win64
  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;
  13.   System;Xml;Data;Datasnap;Web;Soap; -Oc:\emb\radstudiorio\200\lib\Win64\release;C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;
  14.   c:\emb\radstudiorio\200\Imports;C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64;c:\emb\radstudiorio\200\include;
  15.   C:\EMB\FirePower\source\Win64\Debug;C:\EMB\FastReport\LIBD26x64 -Rc:\emb\radstudiorio\200\lib\Win64\release;
  16.   C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports;
  17.   C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win64\Debug;
  18.   C:\EMB\FastReport\LIBD26x64 -Uc:\emb\radstudiorio\200\lib\Win64\debug;C:\EMB\FirePower\source\Win64\Debug;c:\emb\radstudiorio\200\lib\Win64\release;
  19.   C:\Users\MsMCMVIIAgain\Documents\Embarcadero\Studio\20.0\Imports;c:\emb\radstudiorio\200\Imports;
  20.   C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64;c:\emb\radstudiorio\200\include;C:\EMB\FirePower\source\Win64\Debug;
  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.   //
  53.   readln;
  54.  
  55. end.
  56.  

Title: Re: Implicit converison, literals and QWORD variable warning
Post by: emailx45 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
  8.   -E.\Win64\Debug -Ic:\emb\radstudio210\lib\Win64\debug;C:\Emb\QuickReport\src\Win64\Debug;C:\Emb\QuickReport\Win64\Debug;
  9.   c:\emb\radstudio210\lib\Win64\release;C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports;c:\emb\radstudio210\Imports;
  10.   C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp\Win64;c:\emb\radstudio210\include;C:\Emb\QuickReport\src
  11.   -LEC:\Users\Public\Documents\Embarcadero\Studio\21.0\Bpl\Win64 -LNC:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp\Win64 -NU.\Win64\Debug
  12.   -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;
  13.   C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports;c:\emb\radstudio210\Imports;
  14.   C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp\Win64;c:\emb\radstudio210\include;C:\Emb\QuickReport\src
  15.   -Rc:\emb\radstudio210\lib\Win64\release;C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports;c:\emb\radstudio210\Imports;
  16.   C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp\Win64;c:\emb\radstudio210\include;C:\Emb\QuickReport\src -Uc:\emb\radstudio210\lib\Win64\debug;
  17.   C:\Emb\QuickReport\src\Win64\Debug;C:\Emb\QuickReport\Win64\Debug;c:\emb\radstudio210\lib\Win64\release;
  18.   C:\Users\Win10User2020\Documents\Embarcadero\Studio\21.0\Imports;c:\emb\radstudio210\Imports;
  19.   C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp\Win64;c:\emb\radstudio210\include;C:\Emb\QuickReport\src -CC -V -VN -VR
  20.   -NBC:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp\Win64 -NHC:\Users\Public\Documents\Embarcadero\Studio\21.0\hpp\Win64 -NO.\Win64\Debug  
  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.   //
  53.   readln;
  54.  
  55. end.
  56.  
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: emailx45 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.  

Title: Re: Implicit converison, literals and QWORD variable warning
Post by: marcov on August 09, 2020, 11:26:03 pm
Try

Code: Pascal  [Select][+][-]
  1.    procedure something (a:int64;b:uint64);
  2.    begin
  3.     writeln(a+b);
  4.    end;
  5.  

And then for varying (small and large, negative and positive) a and b.

And testing $FFFFFFFFFFFFFFFF with VAL() of course
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: emailx45 on August 09, 2020, 11:42:52 pm
Try

Code: Pascal  [Select][+][-]
  1.    procedure something (a:int64;b:uint64);
  2.    begin
  3.     writeln(a+b);
  4.    end;
  5.  

And then for varying (small and large, negative and positive) a and b.

And testing $FFFFFFFFFFFFFFFF with VAL() of course

Int64 (Negative and Positive) / UInt64 accept only POSITIVE values = if negative resulted violate resulted accept

Quote
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. {$APPTYPE CONSOLE}
  4. {$R *.res}
  5.  
  6. uses
  7.   System.SysUtils;
  8.  
  9. procedure something(a: int64; b: uint64);
  10. begin
  11.   writeln(a + b);
  12. end;
  13.  
  14. begin
  15.   try
  16.     writeln('');
  17.     something(1, 1);
  18.     something(int64.MaxValue, uint64.MaxValue);
  19.     readln;
  20.   except
  21.     on E: Exception do
  22.       writeln(E.ClassName, ': ', E.Message);
  23.   end;
  24.  
  25. end.
  26.  

READ the message by compile about using Assigned and UnAssigned types on bottom of screenshots

Dont exist  -UInt64 values

[dcc32 Warning] Project1.dpr(11): W1073 Combining signed type and unsigned 64-bit type - treated as an unsigned type

[dcc64 Warning] Project1.dpr(11): W1073 Combining signed type and unsigned 64-bit type - treated as an unsigned type
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: emailx45 on August 10, 2020, 12:45:29 am
Try
And testing $FFFFFFFFFFFFFFFF with VAL() of course

VAL() function of System.pas
Quote
Code: Pascal  [Select][+][-]
  1. Converts a string that represents an integer (decimal or hex notation) into a number.
  2.  
  3. In Delphi code, Val converts the string value S to its numeric representation,
  4. as if it were read from a text file with Read. Both 0$1234 and 0x1234 are
  5. the hexadecimal notations supported.
  6.  
  7. S is a string-type expression; it must be a sequence of characters that form
  8. a signed real number, such as "1", "-2" or "+3". Other than the optional sign
  9. at the beginning, all characters must be digits; decimal or thousands
  10. separators are not supported.
  11.  
  12. V is an integer-type or real-type variable. If V is an integer-type variable, S
  13. must form a whole number.
  14.  
  15. Code is a variable of type Integer.
  16.  
  17. If the string is invalid, the index of the offending character is stored in Code;
  18. otherwise, Code is set to zero. For a null-terminated string, the error
  19. position returned in Code is one larger than the actual zero-based index of
  20. the character in error.
  21.  

RAD STUDIO 10.3.3  Rio or RAD 10.4 Sydney same procedure
no debugging
no range checking


In all case tested, the values was:
S  $FFFFFFFFFFFFFFFF
V  18446744073709551615
Code   0


Quote
Code: Pascal  [Select][+][-]
  1. program Project2;
  2.  
  3. {$APPTYPE CONSOLE}
  4. {$R *.res}
  5.  
  6. uses
  7.   System.SysUtils;
  8.  
  9. var
  10.   s   : string;
  11.   V   : UInt64; // my choice
  12.   Code: Integer; // should be Interger
  13.  
  14. begin
  15.   try
  16.     writeln('');
  17.     writeln('');
  18.     s := '$FFFFFFFFFFFFFFFF'; // should be Int64 type
  19.     val(s, V, Code);
  20.     writeln('s := $FFFFFFFFFFFFFFFF - val(s, V, Code);');
  21.     writeln('');
  22.     writeln(V);
  23.     readln;
  24.   except
  25.     on E: Exception do
  26.       writeln(E.ClassName, ': ', E.Message);
  27.   end;
  28.  
  29. end.
  30.  
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: FPK on August 11, 2020, 08:13:04 pm

Code: Pascal  [Select][+][-]
  1. program Project2;
  2.  
  3. {$APPTYPE CONSOLE}
  4. {$R *.res}
  5.  
  6. uses
  7.   System.SysUtils;
  8.  
  9. var
  10.   s   : string;
  11.   V   : UInt64; // my choice
  12.   Code: Integer; // should be Interger
  13.  
  14. begin
  15.   try
  16.     writeln('');
  17.     writeln('');
  18.     s := '$FFFFFFFFFFFFFFFF'; // should be Int64 type
  19.     val(s, V, Code);
  20.     writeln('s := $FFFFFFFFFFFFFFFF - val(s, V, Code);');
  21.     writeln('');
  22.     writeln(V);
  23.     readln;
  24.   except
  25.     on E: Exception do
  26.       writeln(E.ClassName, ': ', E.Message);
  27.   end;
  28.  
  29. end.
  30.  

It must be int64 of course! The "root" of the "problem" is that FPC's val (not StrToInt, not any thing else but val) for int64 (!) accepts $ffffffffffffffff. If it does not, the compiler will not read $ffffffffffffffff as int64. Of course, changing this will probably open pandoras box and probably break a lot of code, but this is how it could be changed. Everything else is a hack.
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: nanobit on August 11, 2020, 09:38:14 pm
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.
2) If intVar has type uint64, then intVar becomes high(uint64).
3) Both get (code = 0).

It's like in Delphi assignment:
i64 := -$1;  // fully compatible
i64 := $ffffffffffffffff; // implicit cast with out-of-range warning, but -1 still is assigned
u64 := $ffffffffffffffff; // fully compatible

I mentioned the Delphi implicit typecast in:
https://forum.lazarus.freepascal.org/index.php/topic,50968.0.html
Title: Re: Implicit converison, literals and QWORD variable warning
Post by: FPK on August 11, 2020, 10:27:06 pm
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.

Whatever it does, it accepts $ffffffffffffffff as a valid int64.
TinyPortal © 2005-2018