Forum > General

StrToInt not raising an error when string overflowing Integer

<< < (3/3)

Bart:
OK, the behaviour for X86_64 is inconsistent with that for i386 (at least on Windows).
Notice that the internal working of Val() has changed in fpc main, and AFAIK these changes are not merged into 3.2 fixes.

Consider this simple example:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---uses  SysUtils; procedure TestValSignedTooHigh;var  I8: Int8;  I16: Int16;  I32: Int32;  I64: Int64;  Err: Integer;begin  {$R+}  writeln('TestValSignedTooHigh: RangeCheck=ON');  try    Val('128',I8,Err);    if Err<>0 then writeln('128: Err=',Err) else writeln('128 -> ',I8,' [???]')  except    on E: ERangeError do writeln('128: RangeCheckError !!');  end;  try    Val('32768',I16,Err);    if Err<>0 then writeln('32768: Err=',Err) else writeln('32768 -> ',I16,' [???]')  except    on E: ERangeError do writeln('32768: RangeCheckError !!');  end;  try    Val('2147483648',I32,Err);    if Err<>0 then writeln('2147483648: Err=',Err) else writeln('2147483648 -> ',I32,' [???]')  except    on E: ERangeError do writeln('2147483648: RangeCheckError !!');  end;  try    Val('9223372036854775808',I64,Err);    if Err<>0 then writeln('128: Err=',Err) else writeln('9223372036854775808 -> ',I64,' [???]')  except    on E: ERangeError do writeln('9223372036854775808: RangeCheckError !!');  end;    {$R-}  writeln('TestValSignedTooHigh: RangeCheck=OFF');  try    Val('128',I8,Err);    if Err<>0 then writeln('128: Err=',Err) else writeln('128 -> ',I8,' [???]')  except    on E: ERangeError do writeln('128: RangeCheckError !!');  end;  try    Val('32768',I16,Err);    if Err<>0 then writeln('32768: Err=',Err) else writeln('32768 -> ',I16,' [???]')  except    on E: ERangeError do writeln('32768: RangeCheckError !!');  end;  try    Val('2147483648',I32,Err);    if Err<>0 then writeln('2147483648: Err=',Err) else writeln('2147483648 -> ',I32,' [???]')  except    on E: ERangeError do writeln('2147483648: RangeCheckError !!');  end;  try    Val('9223372036854775808',I64,Err);    if Err<>0 then writeln('128: Err=',Err) else writeln('9223372036854775808 -> ',I64,' [???]')  except    on E: ERangeError do writeln('9223372036854775808: RangeCheckError !!');  end;end; procedure TestValSignedTooLow;var  I8: Int8;  I16: Int16;  I32: Int32;  I64: Int64;  Err: Integer;begin  {$R+}  writeln('TestValSignedTooLow: RangeCheck=ON');  try    Val('-129',I8,Err);    if Err<>0 then writeln('-129: Err=',Err) else writeln('129 -> ',I8,' [???]')  except    on E: ERangeError do writeln('-129: RangeCheckError !!');  end;  try    Val('-32769',I16,Err);    if Err<>0 then writeln('-32769: Err=',Err) else writeln('-32769 -> ',I16,' [???]')  except    on E: ERangeError do writeln('-32768: RangeCheckError !!');  end;  try    Val('-2147483649',I32,Err);    if Err<>0 then writeln('-2147483649: Err=',Err) else writeln('-2147483649 -> ',I32,' [???]')  except    on E: ERangeError do writeln('-2147483649: RangeCheckError !!');  end;  try    Val('-9223372036854775809',I64,Err);    if Err<>0 then writeln('-9223372036854775809: Err=',Err) else writeln('-9223372036854775809 -> ',I64,' [???]')  except    on E: ERangeError do writeln('-9223372036854775809: RangeCheckError !!');  end;   {$R-}  writeln('TestValSignedTooLow: RangeCheck=OFF');  try    Val('-129',I8,Err);    if Err<>0 then writeln('-129: Err=',Err) else writeln('129 -> ',I8,' [???]')  except    on E: ERangeError do writeln('-129: RangeCheckError !!');  end;  try    Val('-32769',I16,Err);    if Err<>0 then writeln('-32769: Err=',Err) else writeln('-32769 -> ',I16,' [???]')  except    on E: ERangeError do writeln('-32768: RangeCheckError !!');  end;  try    Val('-2147483649',I32,Err);    if Err<>0 then writeln('-2147483649: Err=',Err) else writeln('-2147483649 -> ',I32,' [???]')  except    on E: ERangeError do writeln('-2147483649: RangeCheckError !!');  end;  try    Val('-9223372036854775809',I64,Err);    if Err<>0 then writeln('-9223372036854775809: Err=',Err) else writeln('-9223372036854775809 -> ',I64,' [???]')  except    on E: ERangeError do writeln('-9223372036854775809: RangeCheckError !!');  end;end;  begin  {$ifdef cpu32}  writeln('32-bit CPU');  {$endif}  {$ifdef cpu64}  writeln('64-bit CPU');  {$endif}  TestValSignedTooHigh;  writeln;  TestValSignedTooLow;  writeln;end.
On 32-bit:

--- Code: ---32-bit CPU
TestValSignedTooHigh: RangeCheck=ON
128: Err=3
32768: Err=5
2147483648: Err=10
128: Err=19
TestValSignedTooHigh: RangeCheck=OFF
128: Err=3
32768: Err=5
2147483648: Err=10
128: Err=19

TestValSignedTooLow: RangeCheck=ON
-129: Err=4
-32769: Err=6
-2147483649: Err=11
-9223372036854775809: Err=20
TestValSignedTooLow: RangeCheck=OFF
-129: Err=4
-32769: Err=6
-2147483649: Err=11
-9223372036854775809: Err=20

--- End code ---

All this as was designed: Val() should fail and set the error variable if conversion fails.
See the associated bugreport and the suggestion in to improve the documentation after these changes.

On 64-bit however:

--- Code: ---64-bit CPU
TestValSignedTooHigh: RangeCheck=ON
128: RangeCheckError !!
32768: RangeCheckError !!
2147483648: RangeCheckError !!
128: Err=19
TestValSignedTooHigh: RangeCheck=OFF
128 -> -128 [???]
32768 -> -32768 [???]
2147483648 -> -2147483648 [???]
128: Err=19

TestValSignedTooLow: RangeCheck=ON
-129: RangeCheckError !!
-32768: RangeCheckError !!
-2147483649: RangeCheckError !!
-9223372036854775809: Err=20
TestValSignedTooLow: RangeCheck=OFF
129 -> 127 [???]
-32769 -> 32767 [???]
-2147483649 -> 2147483647 [???]
-9223372036854775809: Err=20

--- End code ---

IIRC then there are seperate intrinsics for 64-bit Val()...

Bart

Bart:
Reported as Issue #41136.

[ETA]Seems to be resolved in a more recent version of fpc main[/ETA]

Bart

PascalDragon:

--- Quote from: ALLIGATOR on February 05, 2025, 05:28:25 pm ---In general, the git version has only pluses and no minuses.
--- End quote ---

FPC main has significant problems with unexpected recompilations in more complex unit scenarios since last summer and thus is not even remotely ready for a release.

ALLIGATOR:

--- Quote from: PascalDragon on February 06, 2025, 10:31:39 pm ---FPC main has significant problems with unexpected recompilations in more complex unit scenarios since last summer and thus is not even remotely ready for a release.

--- End quote ---

I don't see a big problem)
I'm an amateur, not a professional programmer and I have very little software, it doesn't affect me - so I use FPC [main][head].
For those who are critical - they can use FPC[main][881eb0fab5bea2ca1cc283d2aa76d75a1904458e] - as a previous commit before introducing tasks (https://gitlab.com/freepascal.org/fpc/source/-/commit/5298e25c8420f43587d174c6d549f688f514a04a), as far as I understand - so far there is a problem with them.

Besides, if more people use [main][head] - they will find more bugs, there will be better testing, there will be more test cases and maybe even someone will find a suitable, convenient and minimal example that easily replicates the problem with tasks )
In other words, the more you use FPC[main] - the more you help the development of FPC and the release of the new long awaited version )

but again, if this problem bothers anyone, you can always use FPC[main][good commit] and it will be better than good old 3.2.2 )

Navigation

[0] Message Index

[*] Previous page

Go to full version