Attributo: estimated-stack-usage
Il pragma fornisce un valore stimato per il requisito della dimensione dello stack.
I metodi con chiamate ricorsive non possono superare un controllo dello stack perché non è possibile determinare l'utilizzo dello stack. Di conseguenza, viene emesso un avviso. Per evitare questo avviso, puoi assegnare al metodo un valore stimato (in byte) per il requisito della dimensione dello stack. Quindi il metodo supera correttamente il controllo dello stack.
Sintassi
{attribute 'estimated-stack-usage' := ' <estimated stack size in bytes> '}
Inserisci posizione: prima riga sopra la parte di dichiarazione del metodo.
{attribute 'estimated-stack-usage' := '127'} // 127 bytes METHOD PUBLIC DoIt : BOOL VAR_INPUT END_VAR
Per ulteriori informazioni, vedere: chiamata al metodo
Chiamata ricorsiva al metodo
All'interno della sua implementazione, un metodo può chiamare se stesso, sia direttamente tramite il THIS
puntatore o tramite una variabile locale per il blocco funzione assegnato.
Suggerimento
Utilizzare le ricorsioni principalmente per l'elaborazione di tipi di dati ricorsivi come gli elenchi collegati. In generale, si consiglia di prestare attenzione quando si utilizza la ricorsione, poiché le ricorsioni inaspettatamente profonde possono causare overflow dello stack e tempi di fermo macchina.
Il seguente programma PLC_PRG
calcola il fattoriale di un numero in FB_Factorial
blocco funzione in modo diverso, ciascuno nel proprio metodo.
Metodo
m_Iterative
: IterativoMetodo
m_Pragmaed
: ricorsivo con soppressione degli avvisiMetodo
m_Recursive
: RicorsivoMetodo
m_Temp
: Temporaneo con soppressione degli avvisi
Viene emesso un avviso per il m_Recursive
solo metodo.

// 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
Solo il m_Recursive
emette un avviso quando il programma viene eseguito.
