Reentrant function

2017-06-27
2017-07-01
  • josepmariarams - 2017-06-27

    Hi all.

    Do you know if it is possible to call a function from himself in st.

    If yes, how.

    If I do:

    Funtion factorial:lreal
    Var_input
    Value:lreal
    End_var

    If(value<2) then
    Factorial:=1
    Else
    Factorial:=value*factorial(value-1)
    End_if

    Returns an error

     
  • Joan M - 2017-06-27

    Hi Josep!

    It looks like you can't do that with a function...

    Recursion is not handled gracefully by Codesys.

    The closest option here is to use a function block as:

    FUNCTION_BLOCK fb_Recursiu
    VAR_INPUT
    Β  Β i : INT := 0;
    END_VAR
    VAR_OUTPUT
    Β  Β iResult : INT := 0;
    END_VAR
    VAR
    END_VAR
    -----------------------------------------------
    IF (i < 1)
    THEN
    Β  Β i := 0;
    ELSE
    Β  Β i := i - 1;
    Β  Β THIS^();
    END_IF
    iResult := i;
    

    And call it like this:

    fbRecursiu(i := iStart, iResult => iResult);
    

    That could be solved the day functions can be pointed by pointers... or when recursion worked as expected...

    Hope this helps...

     
  • josepmariarams - 2017-06-27

    Thanks Joan.

    I had not thought on this possibility, use an Fb. I will have it in mind.

    At the moment I had solved my problem with an for loop. But sometimes recursion is the most elegant solution.

     
  • Anonymous - 2017-07-01

    Originally created by: scott_cunningham

    One word of caution - Recursion can spell trouble for stack size and other "behind the scenes" mechanisms. If you are dealing with Machine controllers and time sensitive field uses where their number one job is to not crash the whole machine, recursive solutions can be "risky" (just like for/next loops).

     

Log in to post a comment.