Skip to main content

Attribut : utilisation estimée de la pile

Le pragma fournit une valeur estimée pour l'exigence de taille de pile.

Les méthodes avec des appels récursifs ne peuvent pas réussir une vérification de la pile car l'utilisation de la pile ne peut pas être déterminée. En conséquence, un avertissement est émis. Pour éviter cet avertissement, vous pouvez donner à la méthode une valeur estimée (en octets) pour l'exigence de taille de pile. Ensuite, la méthode réussit la vérification de la pile.

Syntaxe

{attribute 'estimated-stack-usage' := ' <estimated stack size in bytes> '}

Emplacement d'insertion : première ligne au-dessus de la partie déclaration de la méthode.

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


Pour plus d'informations, consultez : appel de méthode

Appel de méthode récursif

Au sein de son implémentation, une méthode peut s'appeler elle-même, soit directement au moyen du THIS pointeur ou au moyen d'une variable locale pour le bloc fonction affecté.

Astuce

Utilisez les récursions principalement pour traiter des types de données récursifs tels que des listes chaînées. En général, nous recommandons d'être prudent lors de l'utilisation de la récursivité, car des récursions profondes inattendues peuvent provoquer un débordement de la pile et des temps d'arrêt de la machine.

Exemple 265. Calcul de la factorielle

Le programme suivant PLC_PRG calcule la factorielle d'un nombre dans FB_Factorial bloc fonction d'une manière différente, chacun dans sa propre méthode.

  • Méthode m_Iterative: Itératif

  • Méthode m_Pragmaed: Récursif avec suppression des avertissements

  • Méthode m_Recursive: Récursif

  • Méthode m_Temp: Temporaire avec suppression d'avertissement

Un avertissement est émis pour le m_Recursive méthode uniquement.

_cds_img_example_pragma_estimate_stack_usage.png
// 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

Seulement le m_Recursive émet un avertissement lorsque le programme est exécuté.

_cds_img_example_pragma_estimate_stack_usage_in_runtime.png