0

I realized I don't fully understand how Arduino code handles variable lifetime. My tendency is to keep variables in the narrowest scope (which I realize isn't as important in Arduino code, but, habits...). But how inefficient is this?

Given these possible variations:

 const int c1 = 2, c2 = 7, c3 = 9;

 void functy();

 int foo[3] = {c1 | c2, c3, c2 | c3};

 static int foo[3] = {c1 | c2, c3, c2 | c3};

 const int foo[3] = {c1 | c2, c3, c2 | c3};

  ....

In case 1, foo is both allocated and initialized each call.

In case 2, foo is allocated only once, but is it initialized on each call?

In case 3 I assume that allocation and initialization are done only once? Is that true?

2

Here's a pretty definitive list for you:

// Allocated once in the global area and assigned during 
// program startup
int foo = 1;

// May not even be allocated - the compiler will most likely
// optimise it out.
const int foo = 1;

// Allocated once and assigned during program startup. Cannot be
// accessed from outside the file.
static int foo = 1;

// The static here has no real effect.
static const int foo = 1;

void function() {
    // Allocated in the stack each call and initialised each call.
    // Only accessible from inside this function.
    int foo = 1;

    // Allocated in the global area and initialized on the first call
    // of the function. Only accessible from inside this function.
    static int foo = 1;

    // May not be allocated at all. Only accessible from inside
    // this function.
    const int foo = 1;
}

Note that non-simple const values, things like arrays and strings, depending on the architecture (i.e., if it's a Harvard architecture or not) may be copied into a block of global RAM for simpler access. See PROGMEM in the Arduino Reference Manual for more information.

4
  • Thanks, that does seem to cover it. But in case 3 (const array) I assume the compiler can't optimize it away if later in the function the array is accessed through a passed-in variable index. In that case, is the memory allocated and initialized at compile time?
    – Jim Mack
    Sep 7 '17 at 14:15
  • 1
    Yes. If it is PROGMEM then it is stored only in flash and special instructions are used to access it. If it's not PROGMEM it gets copied into the global ram area at boot time and that ram address is used instead.
    – Majenko
    Sep 7 '17 at 16:04
  • JimMack, Arduino use gcc with LTO (Link Time Optimization), that means a further overall optimization. The Arduino Uno uses an Atmega microcontroller which has 32 registers. Although the gcc compiler does not use all those 32 registers for maximum optimization, locally declared variables might stay in registers and might not exist on the stack. I think the list by @Majenko is not "definitive" but rather "how it is supposed to work in theory".
    – Jot
    Sep 8 '17 at 5:13
  • @Jot That's pretty definitive. Pretty as in "fairly" (not totally), not pretty as in cute.
    – Majenko
    Sep 8 '17 at 9:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.