该pragma提供了堆栈大小要求的估计值。
具有递归调用的方法无法通过堆栈检查,因为无法确定堆栈的使用情况。因此,发出了警告。为防止出现此警告,可以为方法提供堆栈大小要求的估计值(以字节为单位)。然后,该方法成功通过堆栈检查。
语法
{attribute 'estimated-stack-usage' := '<estimated stack size in bytes>'}
示例
{attribute 'estimated-stack-usage' := '127'} // 127 bytes
METHOD PUBLIC DoIt : BOOL
VAR_INPUT
END_VAR
插入位置:方法声明部分上方的第一行。
方法调用 "部分包含一个使用此pragma的示例。
递归方法调用
在实现过程中,方法可以调用自身,可以通过THIS 指针直接调用,也可以通过指定功能块的局部变量调用。
递归主要用于处理递归数据类型,如链接列表。一般,我们建议在使用递归时小心谨慎,因为意外的深度递归可能会导致堆栈溢出和机器宕机。
示例
阶乘计算
下面的程序PLC_PRG 在FB_Factorial 功能块中以不同的方式计算一个数的阶乘,每种方式都有自己的方法。
-
方法
m_Iterative:迭代 -
方法
m_Pragmaed:带警告抑制的递归 -
方法
m_Recursive:递归 -
方法
m_Temp:临时性警告抑制
仅对m_Recursive 方法发出警告。

// 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
只有m_Recursive 才会在执行程序时发出警告。
