Scope and memory usage of variables question?

Let say I have a variable called test which is of type integer.
Let's define this variable with value of 0 inside loop function and do some operations with it.

void setup() {
  init some stuff....
}
void loop() {
 int test = 0;
 while(i < 20){
     i++;
     Serial.println(i);
  }
}

My question here: Is test variable going to be destroyed and memory for it released after loop function finished it's first loop(because of scope) or on the second pass it will create new variable and take more memory(along with previous definition of the variable) and eventually overflow the stack? I now it's not a reference type but I was wondering how it's done in C and Arduino/ESP32?

Within the while loop it will be overwritten...

...not destroyed and recreated.

test is declared in the loop() function so will only exist whilst the loop() function runs. When loop() ends the memory used by the test variable will be released and may be used for something else.

When the loop() function runs again a new variable named test will be created and memory will be allocated for it, but possibly not the same memory

Note that in your example the test variable is not used so it is quite possible that the compiler will optimise the code by removing it

Can you explain your reasoning there, please?

static int test = 0;

If you make it static, it will be like a global variable in that it's value will be retained from one execution of loop() to the next. However, unlike a global variable, it's scope will be limited to loop(), it won't be visible outside loop()

Thanks, I though it was like that but I wanted to make sure :slightly_smiling_face:

@htopalov

Just to add to this, don't see that as an expensive process. The compiler just sets the variable memory pointer relative to the current stack pointer and moves the stack pointer past all the local variables. so it's basically just and addition (or subtraction) to the stack pointer upon entering the function. the rest is known at compile time (for trivial types. for an instance of a class of course the initialiser is called so it's more involved).

then because you initialise it to zero, a bit of code is generated for that

If you refer to the main.cpp of the core file, the Arduino implementation of loop() is more obvious for native C/C++ programmers:

#include <Arduino.h>

// Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; }

// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }

void setupUSB() __attribute__((weak));
void setupUSB() { }

int main(void)
{
	init();

	initVariant();

#if defined(USBCON)
	USBDevice.attach();
#endif
	
	setup();
    
	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}
        
	return 0;
}
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.