memory used by Float type - strange behaviour

Hello everyone,

i’m trying to optimize my code and i’ve noticed something really weird on using the float type.

At the begining of my sketch i have declared float temp_ext;

More down thru my code i have this declaration

/* Legge la temperatura esterna*/
float readTemp()
{
  float temp_ext = 0.0;                               // valore convertito in temperatura (°C)
  int val = 0;                                        // valore quantizzato dall'ADC [0..1023]
  byte nread = 5;                                     // numero di letture (da 5 a 8)
  float somma = 0.0;                                  // somma delle letture
  for (int i = 0; i < nread; i++)
    {
      val = analogRead( LM35_pin );                   // legge il dato della tensione sul pin 'LM35_pin'
      temp_ext = ( 100.0 *  vref * val ) / 1024.0;    // lo converte in °C
      somma += temp_ext;                              // aggiunge alla somma delle temperature lette
    }
  return ( somma / nread );                           // ne calcola il valore medio
}

as you can see, i have declared another time float temp_ext assigning a value of 0.0

If i compile my program it tells me i’m using 31.772 byte (98%)
If i remove the word “float” and leave just “temp_ext = 0.0;” (without quotations) and i compile my program will occupy more memory and exactly 31.804 byte (98%)!

Why does this happen?

When you put the word float in front of it, it creates a new variable called temp_ext that just happens to have the same name as the one you put up at global scope.

The variable inside the function is probably used inside the function instead of the global variable. Because the local variable is used, perhaps the compiler keeps it in registers and does not allocate memory for it. That means that the compiler can do more optimizations for the loop as well. The resulting code is smaller.

It is not strange, it is perfectly normal :wink:

Arduino sets the compiler to optimize for size. If the compiler would optimize for speed, the resulting size could be larger instead of smaller with the extra variable inside the function.

This is my theory.

By declaring temp_ext as a local variable, the compiler is able to flatten out the loop and remove all of the increment, comparison and branch operations. Essentially, it will turn your code into this

int val = 0;
float somma = 0.0;

val = analogRead( LM35_pin );
somma += ( 100.0 *  vref * val ) / 1024.0; //this line is likely to be optimised down to a few instructions


//repeat the last two lines five times over . . .

By declaring temp_ext as global, the compiler might be reluctant to perform these optimisations and this would probably result in greater code size.

This is just a theory and I'm very interested to hear other opinions on this.

Delta_G:
When you put the word float in front of it, it creates a new variable called temp_ext that just happens to have the same name as the one you put up at global scope.

Variable Scope in C++

Thanks for the reply,
so you mean that it won't read the value inside the global scope but will treat it as a new variable?

marcomaroso:
Thanks for the reply,
so you mean that it won’t read the value inside the global scope but will treat it as a new variable?

I answer my question with the nice link you posted me and for which i thank you :

A program can have same name for local and global variables but value of local variable inside a function will take preference. For example:

Right, the one inside the function is different from the one outside the function. Changes made to the one inside the function won't affect the global one. They might as well have different names. If you want to use the global one in the function, then remove the word "float" from in front of the one in the function.

Delta_G:
Right, the one inside the function is different from the one outside the function. Changes made to the one inside the function won't affect the global one. They might as well have different names. If you want to use the global one in the function, then remove the word "float" from in front of the one in the function.

Thanks, that's what i wanted to know.
So when i put float (in this example, could be int or other) in front i'm declaring a new variable in that scope (not a global scope) and that's why my sketch is occupying less memory, because no value has to be kept in mind globally (or atleast not that one) and so it won't use more memory because it's valid only in the scope. Right?

marcomaroso:
Thanks, that's what i wanted to know.
So when i put float (in this example, could be int or other) in front i'm declaring a new variable in that scope (not a global scope) and that's why my sketch is occupying less memory, because no value has to be kept in mind globally (or atleast not that one) and so it won't use more memory because it's valid only in the scope. Right?

No necessarily. The reason why the code is smaller when you declare that variable as local is because the compiler can better optimise the code.

The compiler can do many optimizations and make many different decisions how to optimize. It is hard to predict.
However, you should not use the same name for two different variables anyway. That is bad programming.