Recent

Author Topic: Possible bug with range checking in StrUtils.IfThen function  (Read 2232 times)

Чебурашка

  • Hero Member
  • *****
  • Posts: 527
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: Possible bug with range checking in StrUtils.IfThen function
« Reply #15 on: December 08, 2023, 11:00:53 pm »
So, the question mow is : "Ifthen" is useful for what ?

I use it quite often because of the compactness.

Color := IfThen(c > 0, red, green);

versus

if c > 0 then Color := red else Color := green;

Of course it is not useable in the cases in which there is something that must be evaluated as input and can raise exceptions.

Also, IMO, when using it one should consider that, even if the evaluations necessary to the IfThen input do not raise exceptions like in the case presented here, it is still necessary to keep in mind that the evaluations have a computational cost and this cost could be also extremely high. So doing it always has an impact on the overall program efficiency.

See this example:
Code: Pascal  [Select][+][-]
  1. program ifthentest;
  2.  
  3. {$mode delphi}
  4.  
  5. uses
  6.   Classes, SysUtils;
  7.  
  8. function A1(): Integer;
  9. begin
  10.   Sleep(2000); // Simulates limited number crunching
  11.   Result := 1;
  12. end;
  13.  
  14. function A2(): Integer;
  15. begin
  16.   Sleep(10000); // Simulates big number crunching
  17.   Result := 2;
  18. end;
  19.  
  20. var
  21.   r: Integer;
  22. begin
  23.   r := IfThen<Integer>(False, A1(), A2());
  24.  
  25.   //if False then
  26.   //  r := A1()
  27.   //else
  28.   //  r := A2();
  29. end.
  30.  

It always take 12000 msec to complete even if you put True. While the commented part takes 2000 or 10000 depending on condition.
« Last Edit: December 08, 2023, 11:19:47 pm by Чебурашка »
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Paolo

  • Sr. Member
  • ****
  • Posts: 494
Re: Possible bug with range checking in StrUtils.IfThen function
« Reply #16 on: December 09, 2023, 09:28:23 am »
Exactly, it is counter intuitive, l'll never use it. One is expecting doing "then" or "else" branch not both (as you pointed out it is expecially true for heavy computation).

PascalDragon

  • Hero Member
  • *****
  • Posts: 5416
  • Compiler Developer
Re: Possible bug with range checking in StrUtils.IfThen function
« Reply #17 on: December 10, 2023, 09:46:00 pm »
One is expecting doing "then" or "else" branch not both (as you pointed out it is expecially true for heavy computation).

If one is expecting that, then one doesn't know the language. IfThen is an ordinary function, thus the ordinary rules for functions apply.
Your code didnt work for me, I had to use specialize:

Code: Pascal  [Select][+][-]
  1. Edit1.Text := specialize IfThen<String>(lIndex>=1, CEth[lIndex-1], 'tralllla');

FPC trunk, no problems, no range errors

That is likely on an artifact of either settings or ”luck”. The generic IfThen<> is as much an ordinary function as any other ordinary function, so parameters will be evaluated at the time of the call, no matter if the function is inlined or not (because inlined code is supposed to behave identical to non-inlined one). So if it doesn't trigger a range check for you, then you either don't have range checks enabled when compiling your code or the memory just happens to be valid enough to not trigger another exception.

Paolo

  • Sr. Member
  • ****
  • Posts: 494
Re: Possible bug with range checking in StrUtils.IfThen function
« Reply #18 on: December 11, 2023, 05:38:23 pm »
Quote
IfThen is an ordinary function

that is clear, but at first glance one can think it is a one-to-one replacement of construct if..then..else, but this is not the case as in this topic evidenced.

I banned IfThen in my code.

ccrause

  • Hero Member
  • *****
  • Posts: 838
Re: Possible bug with range checking in StrUtils.IfThen function
« Reply #19 on: December 12, 2023, 08:30:41 am »
Quote
IfThen is an ordinary function

that is clear, but at first glance one can think it is a one-to-one replacement of construct if..then..else, but this is not the case as in this topic evidenced.
It seems as if the expectation that IfThen is a compact notation for the normal if then else construct (which does make sense to some extent).  This cannot be handled by a function call, since it will lead to all the side effects mentioned in this discussion.  Rather, a compiler intrinsic could be used to expand IfThen into an equivalent if..then..else structure.  This would make it more generally useful and similar (at least I think so) to the C shorthand if..else ternary operator.

Whether this is actually in agreement with the Pascal language philosophy is of course debatable. But then again we already have the existence of the IfThen functionality...

Чебурашка

  • Hero Member
  • *****
  • Posts: 527
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: Possible bug with range checking in StrUtils.IfThen function
« Reply #20 on: December 12, 2023, 08:37:45 am »
I banned IfThen in my code.

I believe ifthen is useful in many situations and I will keep using it.
But I am aware that ifthen is not if..then..else.
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Thaddy

  • Hero Member
  • *****
  • Posts: 13934
  • Probably until I exterminate Putin.
Re: Possible bug with range checking in StrUtils.IfThen function
« Reply #21 on: December 13, 2023, 07:00:51 am »
This discussion may be of interest to ifthen haters or lovers. Pay attention to my last example, which is also in the documentation.

https://gitlab.com/freepascal.org/fpc/source/-/issues/34012
Specialize a type, not a var.

 

TinyPortal © 2005-2018