c++ – Why are local variables avoided in Arduino?

Question:

In several code examples for Arduino I notice that there is almost no use of variables in local scope. One of the examples present in the IDE: Analog > AnalogInput :

int sensorPin = A0;
int ledPin = 13;
int sensorValue = 0;

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  sensorValue = analogRead(sensorPin);
  digitalWrite(ledPin, HIGH);
  delay(sensorValue);
  digitalWrite(ledPin, LOW);
  delay(sensorValue);
}

The sensorValue variable is global, while its use is only inside the loop function. Another case is the Moving-Average-Filter library. A part of the code:

#define MAX_DATA_POINTS 20

class MovingAverageFilter {
public:
  MovingAverageFilter(unsigned int newDataPointsCount);
  float process(float in);

private:
  float values[MAX_DATA_POINTS];
  int k;
  int dataPointsCount;
  float out;
  int i;
};

Here the members out and i are used only in process , they must be local:

float MovingAverageFilter::process(float in) {
  out = 0;

  values[k] = in;
  k = (k+1) % dataPointsCount;

  for (i=0; i<dataPointsCount; i++) {
    out += values[i];
  }

  return out/dataPointsCount;
}

Using variables in this way seems absurd to me. Is this on purpose? If yes, what is the reason?

The only possibility I can imagine is that the address of local variables would be known at compile time, so they can be accessed regardless of the stack register. Does it really make a difference?

But in the case of the class, I can't see how it could be faster to read an object through the this pointer than to read it from the stack, relative to the registered one.

Another explanation might be to avoid having to allocate a stack frame to the function. But this allocation should be as simple as incrementing a register, I don't understand why it should be avoided. Also functions that take arguments will have a stack frame anyway.

Answer:

I researched it and didn't find any good answers about it. The reasons I was able to raise are the following:

  • Programs written for Arduino are generally quite simple and there is little memory available. As a result, few people care much about modularization and encapsulation in Arduino programs.

  • Arduino doesn't use a single main() method to execute the program. Instead, it uses two independent setup() and loop() methods. The result of this is that in order for you to use within a loop() what was defined in setup() , you end up being forced to use global variables.

  • Often the variables used in the loop() method must be remembered between one iteration and another. This makes you end up being forced to use global variables.

  • Arduino is too simple and limited for you to use events, callbacks and messaging effectively.

  • Most of the examples are written for beginners who know little about C, so everything is a little too simplified. Furthermore, most Arduino users do not have much interest, practice or training in software programming, as their focus is on hardware.

Helpful but inconclusive discussions can be found here and here .

In conclusion: I recommend following good traditional programming practices. Constants can be easily optimized by the compiler, so you can declare them in global scope without problems (the problem with global variables is when the value changes, which constants don't). Anything that might change in value is better off in a local scope, unless you don't have a choice. If you are going to use global scope, remember the static modifier to make the variable private and make getters and setters functions available if you need to export it.

Scroll to Top