static "unsigned long" takes eight bytes of RAM when initialized. How come?

Hello everyone,

I've noticed that one of my functions is using twice as much RAM as I expected and since this is a pattern I use quite often, I was curious whether anyone knows why. Here is the function in question:

void toggle_pin() {
  static unsigned long last_call = micros();
  if(micros() - last_call > 72) {
    digitalWrite(1,HIGH);
    digitalWrite(1,LOW);
    last_call = micros();
  }
}

Basically the idea here is that if you call this function repeatedly, it will toggle the pin no faster than every 72us. I tend to use this pattern quite a bit in my code.

However, I found this particular function uses eight bytes of RAM, rather than just the 4 needed to store the "unsigned long". Interestingly, a simple change saved four bytes of RAM:

void toggle_pin() {
  static unsigned long last_call = 0;
  if(micros() - last_call > 72) {
    digitalWrite(1,HIGH);
    digitalWrite(1,LOW);
    last_call = micros();
  }
}

It sounds like the compiler allocates more memory when I initialize the static variable to the value of micros(). Does anyone know why this is so? It sounds like a compiler issue to me.

-- Marcio

Here's another one, but it has a simpler explanation (I think):

class MenuScreen {
  public:
    virtual void update()    = 0;
    virtual void onEntry()   = 0;
    virtual void onExit()    = 0;
    virtual void onButton()  = 0;
    virtual void printName() = 0;
};

class Screen1 : public MenuScreen {
    void update()    {};
    void onEntry()   {};
    void onExit()    {};
    void onButton()  {};
    void printName() {};
};

class Screen1 s1;

MenuScreen *current = 0;

void setup( ) {
  current = &s1;    // Comment this out to reduce memory use by 18 bytes
  current->update();
}

void loop() {
}

In this one, if you comment out that one line, the memory use goes down by 18 bytes. I believe this one is caused by GCC storing the virtual function table in RAM, rather than storing it in PROGMEM, as it probably should.

I suppose that until this is fixed, virtual functions are expensive on the Arduino!

last_call has to be initialized once, to the current value of millis, the first time toggle_pin is called. The amount of SRAM needed to ensure that happens is greater than zero.

I suppose that until this is fixed, virtual functions are expensive on the Arduino!

No. Think about what happens if you do not assign a value to current. The compiler is smart enough to figure out that you can't call update() of a non-existent instance, so the whole call to update() gets dumped in the bit-bucket.

When you DO assign a value to current, then the call must happen.