Main Content

Higher Estimate of Size of Local Variables

Total size of all local variables in function

Description

This metric provides a conservative estimate of the total size of local variables in a function. The metric is the sum of the following sizes in bytes:

  • Size of function return value

  • Sizes of function parameters

  • Sizes of local variables

  • Additional padding introduced for memory alignment

Your actual stack usage due to local variables can be different from the metric value.

  • Some of the variables are stored in registers instead of on the stack.

  • Your compiler performs variable liveness analysis to enable certain memory optimizations. For instance, compilers store the address to which the execution returns following the function call. When computing this metric, Polyspace® does not consider these optimizations.

  • Your compiler uses additional memory during a function call. When computing this metric, Polyspace does not consider this hidden memory usage.

  • Compilers optimize temporary variables in different ways. This metric excludes temporary variables. Only the variables that are explicitly declared by the user are considered.

However, the metric provides a reasonable estimate of the stack usage due to local variables.

To determine the sizes of basic types, the software uses your specifications for Target processor type (-target). The metric also takes into account #pragma pack directives in your code.

Examples

expand all

int flag();


int func(int param) {
  int var_1;
  int var_2;
  if (flag()) {
      int var_3;
      int var_4;
    } else {
      int var_5;
    }
}

In this example, assuming 4 bytes for int, the higher estimate of local variable size for funcis 28. The breakup of the size is shown in this table.

VariableSize (in Bytes) Running Total
Return value4 4
Parameter param48
Local variables var_1 and var_24+4=816
Local variables defined in the if condition

(4+4)+4=12

The size of variables in the first branch is eight bytes. The size in the second branch is four bytes. The sum of the two branches is 12 bytes.

28

No padding is introduced for memory alignment because all the variables involved have the same type.

char func(char param) {
  int var_1;
  char var_2;
  double var_3;
}

In this example, assuming one byte for char, four bytes for int and eight bytes for double and four bytes for alignment, the higher estimate of local variable size for func is 20. The alignment is usually the word size on your platform. In your Polyspace project, you specify the alignment through your target processor. For more information, see the Alignment column in Target processor type (-target).

The breakup of the size is shown in this table.

VariableSize (in Bytes)Running Total
Return value1 1
Additional padding introduced before param is stored

0

No memory alignment is required because the next variable param has the same size.

1
Parameter param12
Additional padding introduced before var_1 is stored

2

Memory must be aligned using padding because the next variable var_1 requires four bytes. The storage must start from a memory address at a multiple of four.

4
var_148
Additional padding introduced before var_2 is stored

0

No memory alignment is required because the next variable var_2 has smaller size.

8
var_219
Additional padding introduced before var_3 is stored

3

Memory must be aligned using padding because the next variable var_3 has eight bytes. The storage must start from a memory address at a multiple of the alignment, four bytes.

12
var_3820

The rules for the amount of padding are:

  • If the next variable stored has the same or smaller size, no padding is required.

  • If the next variable has a greater size:

    • If the variable size is the same as or less than the alignment on the platform, the amount of padding must be sufficient so that the storage address is a multiple of its size.

    • If the variable size is greater than the alignment on the platform, the amount of padding must be sufficient so that the storage address is a multiple of the alignment.

class MySimpleClass {
  public:
    
    MySimpleClass() {};
    
    MySimpleClass(int) {};
    
    ~MySimpleClass() {};  
};


int main() {
  MySimpleClass c;
  return 0;
}

In this example, the estimated local variable sizes are:

  • Constructor MySimpleClass::MySimpleClass(): Four bytes.

    The size comes from the this pointer, which is an implicit argument to the constructor. You specify the pointer size using the option Target processor type (-target).

  • Constructor MySimpleClass::MySimpleClass(int): Eight bytes.

    The size comes from the this pointer and the int argument.

  • Destructor MySimpleClass::~MySimpleClass(): Four bytes.

    The size comes from the this pointer.

  • main(): Five bytes.

    The size comes from the int return value and the size of object c. The minimum size of an object is the alignment that you specify using the option Target processor type (-target).

class MyClass {
  public:
    MyClass() {};
    MyClass(int) {};
    ~MyClass() {};
  private:
    int i[10];   
};
void func1(const MyClass& c) {
}


void func2() {
  func1(4);  
}

In this example, the estimated local variable size for func2() is 0. When func2() calls func1(), a temporary object of the class MyClass is created. The temporary variable is excluded from the calculation. Because there are no explicitly declared variables in the body of func2, the reported metric value is 0.

Metric Information

Group: Function
Acronym: LOCAL_VARS_MAX
HIS Metric: No

Version History

Introduced in R2016b