メインコンテンツ

最大スタック使用量

関数内のローカル変数の合計サイズに呼び出し先の最大スタック使用量を加えたもの

説明

このメトリクスは Code Prover 解析のみで報告されます。

このメトリクスでは、関数によるスタック使用量の保守的な推定値が提供されます。メトリクスは、以下のサイズのバイト単位の合計です。

  • ローカル変数サイズのより高い推定値

  • 関数呼び出し先のスタック使用量の最大値。計算では、各呼び出し先の最大スタック使用量を使用します。

    たとえば、この例では、func の最大スタック使用量は func1 または func2 の最大スタック使用量のうちの "大きい方" と同じです。

    void func(void) {
        func1();
        func2();
    }

    関数呼び出しが条件付きステートメントの複数の分岐にある場合、このメトリクスではスタック使用量の最も大きい分岐が考慮されます。

    解析では、どの関数呼び出しが実際に発生するかを解決したら、後からスタック サイズの推定を行います。たとえば、関数呼び出しが到達不能コードで発生する場合、スタック サイズにはその呼び出しは考慮されません。解析では、関数ポインターによる呼び出しを考慮することもできます。

実際のスタック使用量は、このメトリクス値と異なる可能性があります。

  • 一部の変数はスタックではなくレジスタに保存されます。

  • コンパイラでは、メモリの一定の最適化を有効にするために、変数存続の解析が実行されます。このメトリクスを推定する際、Polyspace® ではこれらの最適化が考慮されません。

  • コンパイラでは、関数呼び出し中に追加メモリが使用されます。たとえば、コンパイラは実行で次の関数呼び出しが返る先のアドレスを保存します。このメトリクスを推定する際、Polyspace ではこの隠れたメモリの使用は考慮されません。

  • コンパイラはいくつかの方法で一時変数を最適化します。このメトリクスでは、一時変数が除外されます。ユーザーによって明示的に宣言されている変数のみが考慮されます。

ただし、このメトリクスではスタック使用量の妥当な推定値が提供されます。

基本型のサイズを判断するため、本ソフトウェアではターゲット プロセッサ タイプ (-target)の仕様が使用されます。メトリクスでは、コード内の #pragma pack 命令が考慮されます。

すべて展開する

double func(int);
double func2(int);


double func(int status) {
    double res = func2(status);
    return res;
}


double func2(int status) {
    double res;
    if(status == 0) {
      int temp;    
      res = 0.0;
    }
    else {
      double temp;
      res = 1.0;
    }
    return res;
}

この例では、int を 4 バイト、double を 8 バイトと仮定して、最大スタック使用量は次のようになります。

  • func2:32 バイト

    この値には、パラメーター (4 バイト)、ローカル変数 res (8 バイト)、ローカル変数 temp (2 回カウント。4+8=12 バイト)、および戻り値 (8 バイト) のサイズが含まれます。

    メトリクスでは、2 番目の temp が定義される場合、1 番目の temp は存在しないことを考慮しません。

  • func:52 バイト

    この値には、パラメーター、ローカル変数 res、および戻り値のサイズの合計 20 バイトが含まれます。この値には、呼び出し先の func2 の最大スタック使用量である 32 バイトが含まれます。

void func1(int);
void func2(void);



void func(int status) {
    func1(status);
    func2();
}


void func1(int status) {
    if(status == 0) {
      int val;
    }
    else {
      double val2;
    }
}


void func2(void) {
    double val;
}

この例では、int を 4 バイト、double を 8 バイトと仮定して、最大スタック使用量は次のようになります。

  • func1:16 バイト

    この値にはパラメーター (4 バイト) とローカル変数 val および val2 (4 + 8 = 12 バイト) のサイズが含まれます。

  • func2:8 バイト

  • func:20 バイト

    この値には、パラメーター (4 バイト) および func1func2 の最大スタック使用量 (16 バイト) のサイズが含まれます。

void func1(void);
void func2(void);


void func(int status) {
    if(status==0)
        func1();
    else
        func2();
}

void func1(void) {
    double val;
}


void func2(void) {
    int val;
}

この例では、int を 4 バイト、double を 8 バイトと仮定して、最大スタック使用量は次のようになります。

  • func1:8 バイト

  • func2:4 バイト

  • func:12 バイト

    この値には、パラメーター (4 バイト) および 2 つの分岐の最大スタック使用量 (8 バイト) のサイズが含まれます。

#include <stdarg.h>


void fun_vararg(int x, ...) {
  va_list ap;
  va_start(ap, x);
  int i;
  for (i=0; i<x; i++) {
    int j = va_arg(ap, int);
  }
  va_end(ap);
}



void call_fun_vararg1(void) {
  long long int l = 0;
  fun_vararg(3, 4, 5, 6, l);
}



void call_fun_vararg2(void) {
  fun_vararg(1,0);
}

この関数で、fun_vararg は可変個のパラメーターをもつ関数です。fun_vararg の最大スタック使用量では、最大個数の引数での fun_vararg の呼び出しが考慮されます。最大個数の引数での呼び出しは、5 つの引数 (固定パラメーターに 1 つ、可変パラメーターに 4 つ) がある call_fun_vararg1 での呼び出しです。最大スタック使用量は次のようになります。

  • fun_vararg:36 バイト。

    この値では以下を考慮しています。

    • 固定パラメーター x のサイズ (4 バイト)。

    • 最大個数のパラメーターで呼び出す場合の可変パラメーターのサイズ。その呼び出しには 4 つの可変引数 (3 つの int と 1 つの long long int 変数) があります (3 x 4 + 1 x 8 = 20 バイト)。

    • ローカル変数 ij、および ap のサイズ (12 バイト)。va_list 変数のサイズでは、ターゲットで定義されるポインター サイズが使用されます (この場合、4 バイト)。

  • call_fun_vararg1:44 バイト。

    この値では以下を考慮しています。

    • 5 つの引数がある fun_vararg のスタック サイズ使用量 (36 バイト)。

    • ローカル変数 l のサイズ (8 バイト)。

  • call_fun_vararg2:20 バイト。

    call_fun_vararg2 にはローカル変数がないため、この値は、2 つの引数がある fun_vararg のスタック サイズ使用量と同じです (20 バイト。このうち、12 バイトはローカル変数分で、8 バイトは fun_vararg の 2 つのパラメーター分)。

メトリクス情報

グループ: 関数
頭字語: MAX_STACK
HIS メトリクス:いいえ

バージョン履歴

R2017b で導入

すべて展開する