In an ISR I want to keep things quick. At the same time I want to limit variable scope. Storage space is not a factor.

I have this line:

const char trigs[] = "aAbBcCdDeEfFgGhHiIjJ";

When this is global, the resulting compile stats show:

Sketch uses 3418 bytes (10%) of program storage space. 
Global variables use 431 bytes (21%) of dynamic memory.

When it's inside the function (to limit scope) I get:

Sketch uses 3470 bytes (10%) of program storage space. 
Global variables use 431 bytes (21%) of dynamic memory.

The extra program space is 52 bytes, which is more than the size of the variables, so there must be extra code in there. That might be something to do with initialization checks... but why? Isn't a const already known? If there's a difference in where it's stored, why doesn't global variable space change?

If I prefix this as static const I'm back to the first behavior (3418 / 431).

So the immediate answer is just to use static const, I suppose. But I'm still curious what's going on. Can someone elucidate?

  • Can you show us your entire sketch? – VE7JRO Apr 19 '19 at 23:04
  • @VE7JRO - I don't think that's practical. If it's important to see more context I could try to create a minimal sketch that illustrates this, but it seems pretty straightforward now. Is more context really needed? – Jim Mack Apr 19 '19 at 23:08
  • 1
    with const char* trigs = "aAbBcCdDeEfFgGhHiIjJ"; the size of sketch is always the same for global or local with static or without static. if I call the function twice, the local version without static is better – Juraj Apr 20 '19 at 12:02
  • To optimize for speed, add this in the top of your sketch: #pragma GCC optimize("-O3") – Jot Apr 21 '19 at 3:15

const char trigs[] is an auto - it's allocated on the stack at function entry time - and must be initialized at each invocation. The literal used to do that is stored in globals space, which is why the globals allocation doesn't change.

static const char trigs[] is allocated in globals space and used in place. The symbols' scope is still local, though, so trigs[] isn't visible outside the function.

So why does code space increase by 52 bytes? That seems a lot for copying a string from place to another. So I'll take a guess that the need to copy a string loads a library module that includes it and a few other functions as well.

  • OK, good info. I get that the stack allocation has to occur for variables, but what I guess I missed is that a const would be considered a variable in that sense. On reflection I guess it couldn't be done any other way. – Jim Mack Apr 19 '19 at 23:46
  • 1
    this is not an answer. the question was: why, if it is const and the value is known at compile time, it is not optimized like static? – Juraj Apr 20 '19 at 6:34
  • @Juraj - That was my real question, but with more reading I learned that const here doesn't mean what I naively thought. Here trigs[] is a variable like any other -- the const attribute simply makes it read-only. That's not intuitive to someone coming from a language that has 'true' constants, but it's how the spec is written. – Jim Mack Apr 20 '19 at 11:16

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.