Recent

Author Topic: TryStrToInt declaration question  (Read 6770 times)

lagprogramming

  • Full Member
  • ***
  • Posts: 193
TryStrToInt declaration question
« on: January 17, 2022, 05:31:43 pm »
Hi!
Regarding the "TryStrTo..." functions, we have a single function name to convert strings to single, double or extended, it's TryStrToFloat. Not all CPUs support extended, double, some not even single.
Why do we have TryStrToInt for 32bit variables, TryStrToInt64 for 64bit signed variables and TryStrToQWord for 64bit unsigned variables?
I found this situation when I realized that calling TryStrToInt with a sizeuint parameter may lead to errors when I target x86_64.
I've looked at rtl documentation and I've seen:
Declaration: function TryStrToInt(const s: string; out i: LongInt) : Boolean
Declaration: function TryStrToInt64(const s: string; out i: Int64) : Boolean
Declaration: function TryStrToQWord(const s: string; out Q: QWord) : Boolean
How comes that for 32bit we have a single function(TryStrToInt) with a longint parameter, but for 64bit we have a function for signed integers(TryStrToInt64) and a different function for unsigned integers(TryStrToQWord)?
Thank you!

ASerge

  • Hero Member
  • *****
  • Posts: 1916
Re: TryStrToInt declaration question
« Reply #1 on: January 17, 2022, 08:02:04 pm »
For historical reasons.
The Int64 type was first introduced in Delphi4. And at the same time, the StrToInt64 function was added in addition to the existing StrToInt. Since overlapping functions (introduce in Delphi4 also) do not differ in the type of results, the names were chosen of course different. It is also worth noting that for 32-bit Intel processors, 32-bit integers and 10-bit floating-point numbers (extended) were native. Therefore, the functions StrToInt: Integer and StrToFloat:Extended were native, but StrToInt64: Int64 is optional. In later versions Delphi, TryStrTo... functions were added. With the preservation of names, of course.
The StrToQWord function was added in FPC because the QWord type did not fit into Int64. A similar StrToUInt64 function was also added, but later, in Delphi.

ASerge

  • Hero Member
  • *****
  • Posts: 1916
Re: TryStrToInt declaration question
« Reply #2 on: January 17, 2022, 08:12:18 pm »
Of course, if you don't like a lot of names, you can overload the functions:
Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2. {$LONGSTRINGS ON}
  3.  
  4. uses SysUtils;
  5.  
  6. function TryStrToInt(const S: string; out Value: Int64): Boolean; inline; overload;
  7. begin
  8.   Result := SysUtils.TryStrToInt64(S, Value);
  9. end;
  10.  
  11. function TryStrToInt(const S: string; out Value: QWord): Boolean; inline; overload;
  12. begin
  13.   Result := SysUtils.TryStrToQWord(S, Value);
  14. end;
  15.  
  16. var
  17.   I32: Int32;
  18.   I64: Int64;
  19.   Q: QWord;
  20. begin
  21.   TryStrToInt('1', I32); // Call SysUtils.TryStrToInt
  22.   TryStrToInt('1', I64); // Call SysUtils.TryStrToInt64
  23.   TryStrToInt('1', Q); // Call SysUtils.TryStrToQWord
  24. end.

lagprogramming

  • Full Member
  • ***
  • Posts: 193
Re: TryStrToInt declaration question
« Reply #3 on: January 18, 2022, 01:30:52 pm »
   Let's assume that a developer has a code like this:
Code: Pascal  [Select][+][-]
  1. function foo(StringVariable:string; var Number:integer):boolean;
  2. var
  3.   IntegerVariable: integer;
  4. begin
  5.   {Pascal code}
  6.   if TryStrToInt(StringVariable,IntegerVariable) then...
  7.   {Additional pascal code}
  8.   Number:=IntegerVariable;
  9. end;

   In order to make the above code work nicely and native with 64bit CPUs it's not enough to change the integer types to sizeint.
   According to the slogan "Write once, compile anywhere", if the code in written in a 32bit environment(which means sizeint would have the same size as integer) each and every developer has to realize that TryStrToInt won't work as they expect when the code is compiled in a 64bit environment. Those developers needs some luck to realize that. If the developers realize that their code has a problem in using this function, they must come with a workaround. One workaround is the one presented by ASerge, other approaches might be using conditional compilation syntax like {$IF....} or using the Val routine directly. The approach involving workarounds is far from being crosscompile friendly.

   Wouldn't be better to avoid pushing each and every developer to write workarounds in their code by making TryStrToInt also accept 64bit integers and then modify existing code in TryStrToInt64 and TryStrToQWord to make it call TryStrToInt? With this approach we would have a clean way of using TryStrToInt routine similar to TryStrToFloat while keeping existing written pascal code compatible, for historical reasons.

Seenkao

  • Sr. Member
  • ****
  • Posts: 399
    • New ZenGL.
Re: TryStrToInt declaration question
« Reply #4 on: January 18, 2022, 01:49:44 pm »
разработчикам в любом случае надо будет приводить тип данных к компилируемой архитектуре. Понятно дело, это не надо будет делать пользователю. Но вот подгонка типов данных под компилируемую архитектуру... этот не очень благодарное дело.

google translate:
developers in any case will need to cast the data type to the compiled architecture. Clearly, the user does not need to do this. But here's the adjustment of data types to the compiled architecture ... this is not a very rewarding job.
Rus: Стремлюсь к созданию минимальных и достаточно быстрых приложений.
Работаю над ZenGL.
Eng: I strive to create applications that are minimal and reasonably fast.
Working on ZenGL. :)

Zoran

  • Hero Member
  • *****
  • Posts: 1726
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: TryStrToInt declaration question
« Reply #5 on: January 18, 2022, 02:50:49 pm »
I agree that you have a point. Only I think that, instead of unifying all to TryStrToInt overloads (could it create some (backwards-/Delphi-) compatibility problems?), perhaps the cleaner solution would be adding a new function TryStrToPtrInt to Sysutils.

Anyway, it's worth making a feature request in bug tracker; do it.
Then further discussion should go there. FPC developers will then decide which approach to take, if any.

And using val directly is not really a big problem.

Thaddy

  • Hero Member
  • *****
  • Posts: 11517
Re: TryStrToInt declaration question
« Reply #6 on: January 18, 2022, 03:06:40 pm »
Note that AFAIK the tryXXX family in trunk has been recently mutilated by the use of exceptions in its implementations. Just counter-intuitive to why those were designed and not Delphi compatible. This is currently only an issue for trunk. That is not "implementation detail", it misses the point of tryxxx.  >:D : Don't rely on exceptions when not needed.
As far as I can see, that is an introduction of dirty code in the RTL.

I hope one see's its ways....
« Last Edit: January 18, 2022, 03:13:50 pm by Thaddy »
Путин преступник. Россияне дезинформированы.

Zoran

  • Hero Member
  • *****
  • Posts: 1726
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: TryStrToInt declaration question
« Reply #7 on: January 18, 2022, 03:25:30 pm »
it misses the point of tryxxx.  >:D : Don't rely on exceptions when not needed.

Of course. StrToInt should call TryStrToInt and only then raise if needed. Not the other way around, first unnecessary raise then catch and discard it.
It's ridiculous.

Thaddy

  • Hero Member
  • *****
  • Posts: 11517
Re: TryStrToInt declaration question
« Reply #8 on: January 18, 2022, 03:55:40 pm »
I saw the Delphi Implementation, so can not provide an uninformed  - un-biased - patch.
I hope it has not made it into a release version.
But it defeats the point.
(btw: original Implementation was correct.)
« Last Edit: January 18, 2022, 05:38:20 pm by Thaddy »
Путин преступник. Россияне дезинформированы.

Bart

  • Hero Member
  • *****
  • Posts: 4689
    • Bart en Mariska's Webstek
Re: TryStrToInt declaration question
« Reply #9 on: January 18, 2022, 06:23:47 pm »
it misses the point of tryxxx.  >:D : Don't rely on exceptions when not needed.

Of course. StrToInt should call TryStrToInt and only then raise if needed. Not the other way around, first unnecessary raise then catch and discard it.
It's ridiculous.

Both in 3.2.2 and in trunk the TryStrToXXX versions just call Val() and in trunk StrToxxx calls TryStrToXXX,whereas in 3.2.2 they call Val().
So, the TryStrToXXX functions do not call StrToXXX and then catch the exception.

Bart

MarkMLl

  • Hero Member
  • *****
  • Posts: 4155
Re: TryStrToInt declaration question
« Reply #10 on: January 18, 2022, 10:48:00 pm »
That is not "implementation detail", it misses the point of tryxxx.  >:D : Don't rely on exceptions when not needed.
As far as I can see, that is an introduction of dirty code in the RTL.

That's particularly unfortunate, since a few weeks ago somebody- neither a newcomer to the forum nor to the language- was criticising the entire library stack due to over-use of exceptions.

How on earth did it get past review? The World wonders...

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Bart

  • Hero Member
  • *****
  • Posts: 4689
    • Bart en Mariska's Webstek
Re: TryStrToInt declaration question
« Reply #11 on: January 18, 2022, 10:59:03 pm »
OK, so which TryStrToXXX functions in trunk have been "mutilated" to use exceptions?
AFAICS none of the TryStrToInt variants.

Bart

PascalDragon

  • Hero Member
  • *****
  • Posts: 3998
  • Compiler Developer
Re: TryStrToInt declaration question
« Reply #12 on: January 19, 2022, 10:31:39 am »
Note that AFAIK the tryXXX family in trunk has been recently mutilated by the use of exceptions in its implementations. Just counter-intuitive to why those were designed and not Delphi compatible. This is currently only an issue for trunk.

There is no issue, cause the Try… functions don't use exceptions.

That is not "implementation detail", it misses the point of tryxxx.  >:D : Don't rely on exceptions when not needed.
As far as I can see, that is an introduction of dirty code in the RTL.

That's particularly unfortunate, since a few weeks ago somebody- neither a newcomer to the forum nor to the language- was criticising the entire library stack due to over-use of exceptions.

How on earth did it get past review? The World wonders...

Nothing did get past review here, cause nothing like Thaddy mentioned happened.

MarkMLl

  • Hero Member
  • *****
  • Posts: 4155
Re: TryStrToInt declaration question
« Reply #13 on: January 19, 2022, 11:00:26 am »
Nothing did get past review here, cause nothing like Thaddy mentioned happened.

@Thaddy, would you like to explain what you think you've seen?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

lagprogramming

  • Full Member
  • ***
  • Posts: 193
Re: TryStrToInt declaration question
« Reply #14 on: January 19, 2022, 11:26:25 am »
   I've looked in the rtl documentation I have and I've seen the following declarations:
Code: Pascal  [Select][+][-]
  1. function IntToStr(Value: LongInt) : string
  2. function IntToStr(Value: Int64) : string
  3. function IntToStr(Value: QWord) : string
  4. function UIntToStr(Value: QWord) : string
  5. function UIntToStr(Value: Cardinal) : string
   Maybe function IntToStr(Value: QWord) : string does the same thing as function UIntToStr(Value: QWord) : string, I don't know.
   In addition to the fact that we have TryStrToFloat working with single, double and extended, the point presenting the above extras is that we have IntToStr functions working with 64bit integers, but we don't have TryStrToInt working with 64bit integers. This can't be good. There is no reason or hint to realize that contrary to the use of TryStrToFloat and IntToStr, a developer must use different function names when he wants to do what he expects from a TryStrToInt function.

 

TinyPortal © 2005-2018