Das Pragma übergibt einen Schätzwert für den Stackgrößenbedarf.
Methoden mit rekursivem Aufruf halten einer Stackprüfung nicht stand, weil der Stackverbrauch nicht ermittelt werden kann. Folglich wird eine Warnung ausgegeben. Um diese Warnung zu unterdrücken, können Sie der Methode einen Schätzwert in Bytes für den Stackgrößenbedarf mitgeben. Dann durchläuft die Methode die Stackprüfung erfolgreich.
Syntax
{attribute 'estimated-stack-usage' := '<estimated stack size in bytes>'}
Beispiel
{attribute 'estimated-stack-usage' := '127'} // 127 bytes METHOD PUBLIC DoIt : BOOL VAR_INPUT END_VAR
Einfügeort: Erste Zeile über dem Deklarationsteil der Methode
Im Kapitel "Methodenaufruf" finden Sie ein Beispiel, das dieses Pragma verwendet.
Rekursiver Methodenaufruf
Innerhalb ihrer Implementierung kann eine Methode sich selbst aufrufen: entweder direkt
mit Hilfe des THIS
-Pointers, oder mit Hilfe einer lokalen Variablen für den zugeordneten Funktionsbaustein.
Verwenden Sie Rekursionen vorwiegend zur Bearbeitung von rekursiven Datentypen wie beispielsweise verketteten Listen. Allgemein ist es ratsam bei der Verwendung von Rekursion vorsichtig zu sein, da es bei unerwartet tiefen Rekursionen zu eine Stacküberlauf und damit zu einem Maschinenstillstand kommen kann."
Beispiel
Berechnung der Fakultät
Das folgende Programm PLC_PRG
berechnet die Fakultät einer Zahl im Funktionsbaustein FB_Factorial
auf unterschiedliche Weise in jeweils einer eigenen Methode.
-
Methode
m_Iterative
: Iterativ -
Methode
m_Pragmaed
: Rekursiv mit Warnungsunterdrückung -
Methode
m_Recursive
: Rekursiv -
Methode
m_Temp
: Temporär mit Warnungsunterdrückung
Nur die Methode m_Recursive
erzeugt eine Warnung.

// 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
Bei der Ausführung des Programms generiert nur die Methode m_Recursive
eine Warnung.
