The pragma provides an estimated value for the stack size requirement.
Methods with recursive calls cannot pass a stack check because stack usage cannot be determined. As a result, a warning is issued. To prevent this warning, you can give the method an estimated value (in bytes) for the stack size requirement. Then the method passes the stack check successfully.
Syntax
{attribute 'estimated-stack-usage' := '<estimated stack size in bytes>'}
Example
{attribute 'estimated-stack-usage' := '127'} // 127 bytes METHOD PUBLIC DoIt : BOOL VAR_INPUT END_VAR
Insert location: First line above the declaration part of the method.
The section "Method call" includes an example that uses this pragma.
Recursive method call
Within its implementation, a method can call itself, either directly by means of the
THIS
pointer, or by means of a local variable for the assigned function block.
Use recursions mainly for processing recursive data types such as linked lists. In general, we recommend to be careful when using recursion, as unexpectedly deep recursions can cause stack overflow and machine downtime.
Example
Calculation of the factorial
The following program PLC_PRG
calculates the factorial of a number in the FB_Factorial
function block in a different way, each in its own method.
-
Method
m_Iterative
: Iterative -
Method
m_Pragmaed
: Recursive with warning suppression -
Method
m_Recursive
: Recursive -
Method
m_Temp
: Temporary with warning suppression
A warning is issued for the m_Recursive
method only.

// Contains the data of the factorial calculation of uiNumber TYPE FACTORIAL_RESULT : STRUCT uiNumber : UINT; udiIterative : UDINT; udiRecursive : UDINT; udiPragmaed : UDINT; udiTemp : UDINT; END_STRUCT END_TYPE PROGRAM PLC_PRG VAR fb_Factorial_A : FB_Factorial; factorial_A : FACTORIAL_RESULT := (uiNumber := 9, udiIterative := 0, udiRecursive := 0, udiPragmaed := 0 ); END_VAR fb_Factorial_A.p_Number := factorial_A.uiNumber; factorial_A.udiIterative := fb_Factorial_A.m_Iterative(); factorial_A.udiRecursive := fb_Factorial_A.m_Recursive(uiN := factorial_A.uiNumber); factorial_A.udiPragmaed := fb_Factorial_A.m_Pragmaed(uiN := factorial_A.uiNumber); factorial_A.udiTemp := fb_Factorial_A.m_Temp(uiN := factorial_A.uiNumber); //Factorial calculation in different ways FUNCTION_BLOCK FB_Factorial VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR uiN : UINT; udiIterative : UDINT; udiPragmaed : UDINT; udiRecursive : UDINT; END_VAR // Iterative calculation METHOD PUBLIC m_Iterative : UDINT VAR uiCnt : UINT; END_VAR m_Iterative := 1; IF uiN > 1 THEN FOR uiCnt := 1 TO uiN DO m_Iterative := m_Iterative * uiCnt; END_FOR; RETURN; ELSE RETURN; END_IF; //Recursive calculation with suppressed warning {attribute 'estimated-stack-usage' := '99'} METHOD PUBLIC m_Pragmaed : UDINT VAR_INPUT uiN : UINT; END_VAR VAR END_VAR m_Pragmaed := 1; IF uiN > 1 THEN m_Pragmaed := uiN * THIS^.m_Pragmaed(uiN := (uiN - 1)); RETURN; ELSE RETURN; END_IF; //Recursive calculation METHOD PUBLIC m_Recursive : UDINT VAR_INPUT uiN : UINT; END_VAR VAR END_VAR m_Recursive := 1; IF uiN > 1 THEN m_Recursive := uiN * THIS^.m_Recursive(uiN := (uiN - 1) ); RETURN; ELSE RETURN; END_IF; // Called by temporary FB instance {attribute 'estimated-stack-usage' := '99'} METHOD PUBLIC m_Temp : UDINT VAR_INPUT uiN : UINT; END_VAR VAR fb_Temp : FB_Factorial; END_VAR m_Temp := 1; IF uiN > 1 THEN m_Temp := uiN * fb_Temp.m_Temp(uiN := (uiN - 1)); RETURN; ELSE RETURN; END_IF; PROPERTY p_Number : UINT uiN := p_Number; //Setter method
Only the m_Recursive
issues a warning when the program is executed.
