Skip to main content

属性:推定スタック使用量

プラグマは、スタックサイズ要件の推定値を提供します。

再帰呼び出しのあるメソッドは、スタックの使用状況を判別できないため、スタックチェックに合格できません。その結果、警告が発行されます。この警告を防ぐために、スタックサイズ要件の推定値(バイト単位)をメソッドに指定できます。次に、メソッドはスタックチェックに正常に合格します。

構文

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

挿入場所:メソッドの宣言部分の上の最初の行。

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


詳細については、以下を参照してください。 メソッド呼び出し

再帰的なメソッド呼び出し

その実装内で、メソッドは、 THIS ポインタ、または割り当てられた機能ブロックのローカル変数を使用します。

ヒント

主にリンクリストなどの再帰データ型を処理するために再帰を使用します。一般に、再帰を使用する場合は注意することをお勧めします。予期しないほど深い再帰は、スタックオーバーフローやマシンのダウンタイムを引き起こす可能性があるためです。

265. 階乗の計算

次のプログラム PLC_PRG の数値の階乗を計算します FB_Factorial それぞれ独自のメソッドで、異なる方法で関数ブロック。

  • 方法 m_Iterative:反復

  • 方法 m_Pragmaed:警告抑制を伴う再帰

  • 方法 m_Recursive:再帰的

  • 方法 m_Temp:警告抑制を伴う一時的な

警告が発行されます m_Recursive メソッドのみ。

_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

のみ m_Recursive プログラムの実行時に警告を発行します。

_cds_img_example_pragma_estimate_stack_usage_in_runtime.png