.
属性‘estimated-stack-usage’
.
.

此编译指令提供了堆栈大小要求的估计值。

具有递归调用的方法无法通过堆栈检查,因为无法确定堆栈使用情况。结果,发出警告。为避免出现此警告,您可以为方法提供堆栈大小要求的估计值(以字节为单位)。然后,该方法成功通过了堆栈检查。

.语法:


 {attribute 'estimated-stack-usage' := '<估计的堆栈大小,以字节为单位>'}
 
.

.例如


{attribute 'estimated-stack-usage' := '127'} // 127 bytes
METHOD PUBLIC DoIt : BOOL
VAR_INPUT
END_VAR
 

插入位置:方法声明部分上方的第一行。

“方法调用”部分包括使用此编译指示的示例。

.
递归方法调用

在其实现中,方法可以直接通过THIS指针或通过所分配功能块的局部变量来调用自身。

 

递归主要用于处理递归数据类型,例如链表。通常,建议使用递归时要小心,因为意外的深度递归会导致堆栈溢出和机器停机。

.
例如
.

.阶乘的计算

. 以下程序PLC_PRG以不同的方式计算FB_Factorial功能块中数字的阶乘,每种方式均采用其自己的方法。

  • 方法m_Iterative:迭代
  • 方法m_Pragmaed:具有警告抑制的递归
  • 方法m_Recursive:递归
  • 方法m_Temp:具有警告抑制功能的临时方法

仅对m_Recursive方法发出警告。


// 包含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
 

执行程序时,只有m_Recursive发出警告。