exponenta event banner

Максимальное использование стека

Общий размер локальных переменных в функции плюс максимальное использование стека вызываемыми абонентами

Описание

Эта метрика отображается только в анализе проверки кода.

Эта метрика обеспечивает консервативную оценку использования стека функцией. Метрика представляет собой сумму этих размеров в байтах:

  • Higher Estimate of Local Variable Size

  • Максимальное значение из использования стека вызываемых функций. В вычислениях используется максимальное использование стека для каждого вызываемого абонента.

    Например, в этом примере максимальное использование стека func совпадает с максимальным использованием стека func1 или func2, в зависимости от того, что больше.

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

    Если вызовы функции находятся в различных ветвях условного оператора, эта метрика учитывает ветвь с наибольшим использованием стека.

    Анализ производит оценку размера стека позже, когда он разрешит, какие вызовы функции действительно происходят. Например, если вызов функции происходит в недостижимом коде, размер стека не учитывает вызов. Анализ также может учитывать вызовы через указатели функций.

Фактическое использование стека может отличаться от метрического значения.

  • Некоторые переменные хранятся в регистрах, а не в стеке.

  • Компилятор выполняет анализ переменной жизнедеятельности для оптимизации памяти. При оценке этой метрики Polyspace ® не учитывает эти оптимизации.

  • Компилятор использует дополнительную память во время вызова функции. Например, компиляторы сохраняют адрес, на который возвращается выполнение после вызова функции. При оценке этой метрики Polyspace не учитывает это использование скрытой памяти.

Однако метрика обеспечивает разумную оценку использования стека.

Чтобы определить размеры основных типов, программное обеспечение использует ваши спецификации для Target processor type (-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 и восемь байт для double, максимальное использование стека:

  • func2: 32 байта

    Это значение включает размеры параметра (4 байта), локальную переменную res (8 байт), локальная переменная temp подсчитано дважды (4 + 8 = 12 байт) и возвращаемое значение (8 байт).

    Метрика не учитывает, что первый temp больше не живет, когда второй temp определяется.

  • func: 52 байта

    Это значение включает размеры параметра, локальной переменной resи возвращаемое значение, в общей сложности 20 байт. Это значение включает 32 байта максимального использования стека вызываемым пользователем, func2.

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 и восемь байт для double, максимальное использование стека:

  • func1: 16 байт

    Это значение включает размеры параметра (4 байта) и локальные переменные val и val2 (4 + 8 = 12 байт).

  • func2: 8 байт

  • func: 20 байт

    Это значение включает размеры его параметра (4 байта) и максимальное использование стека func1 и func2 (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 и восемь байт для double, максимальное использование стека:

  • func1: 8 байт

  • func2: 4 байта

  • func: 12 байт

    Это значение включает размеры его параметра (4 байта) и максимальное использование стека из двух ветвей (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 с максимальным количеством аргументов. Вызов с максимальным количеством аргументов - это вызов в call_fun_vararg1 с пятью аргументами (один для фиксированного параметра и четыре для переменных параметров). Максимальные значения использования стека:

  • fun_vararg: 36 байт.

    Это значение учитывает:

    • Размер фиксированного параметра x (4 байта).

    • Размеры переменных параметров из вызова с максимальным количеством параметров. В этом вызове существует четыре переменных аргумента: три int и один long long int переменная (3 раза 4 + 1 раз 8 = 20 байт).

    • Размеры локальных переменных i, j и ap (12 байт). Размер va_list переменная использует размер указателя, определенный в целевом объекте (в данном случае 4 байта).

  • call_fun_vararg1: 44 байта.

    Это значение учитывает:

    • Использование размера стека fun_vararg с пятью аргументами (36 байт).

    • Размер локальной переменной l (8 байт).

  • call_fun_vararg2: 20 байт.

    С тех пор call_fun_vararg2 не имеет локальных переменных, это значение совпадает с использованием размера стека fun_vararg с двумя аргументами (20 байт, из которых 12 байт для локальных переменных и 8 байт для двух параметров fun_vararg).

Метрическая информация

Группа: Функция
Акроним: MAX_STACK
ЕГО метрика: Нет
Представлен в R2017b