static const memory usage

If the static keyword is used for a constant inside a function, does it have any influence on the compilation?

Suppose a function contains:

static const uint8_t UNO = 1;
static const uint8_t VARIOS[3]{1,2,3};

How much memory RAM do these take? Is the answer the same for AVR and SAMD21?

Static means the memory is not allocated on the heap stack and goes away when the function terminates. So the variable will exist for as long as your program runs. The scope is limited to the function though

Thisstatic const uint8_t UNO = 1;will allocate one byte globally.

This line:static const uint8_t VARIOS[3]{1,2,3}; allocates 3 bytes but does not do what you think...

J-M-L:
Static means the memory is not allocated on the heap and goes away when the function terminates. So the variable will exist for as long as your program runs.

This line:

static const uint8_t VARIOS[3]{1,2,3};

does not do what you think…

Static means the memory is not allocated on the stack

Indeed - exactly what I meant :slight_smile:

Well, I suppose it isn’t allocated on the heap either…:smiley:

That’s a heaping stack of information.

Curious, since both statements are static and constant, would the compiler potentially optimize them away, depending on their use?

static const uint8_t UNO = 1;

The above combination makes zero sense. static const

Yes I never wanted to mention the heap. I meant just to mention the stack where function’s local variables are allocated.

(With static, the variable goes in the bss segment I would say)

larryd:
static const uint8_t UNO = 1;
The above combination makes zero sense. static const

Good point - i focused on static, did not even look at const ... will likely be optimized away indeed

Then this, inside a function:

static const uint8_t VARIOS[3]{1,2,3};

takes global space.

This, inside a function:

const uint8_t VARIOS[3]{1,2,3};

takes stack space.

And, these two, inside a function, take the same amount of stack space and no global space:

const uint8_t VARIOS[3]{1,2,3};
uint8_t VARIOS[3]{1,2,3};

Is that right?

Add an = before your initialization arrayconst uint8_t VARIOS[] = {1,2,3};
If the compilers is smart and depending if you use literals or constant indexes, the array might be optimized out too.

J-M-L:
Add an = before your initialization array

No longer necessary

I learnt something then! Thx

EDIT: it does not seem to be in the spec. Is that a GCC thingy?

larryd:
static const uint8_t UNO = 1;

The above combination makes zero sense. static const

I disagree.

When that line is outside of any function, the 'static' means that the variable UNO is global only to the current file. It's out of scope for functions in any other file, unlike a regular global. The 'const' means the programmer has promised the compiler that he/she will not try to change its value.

When used inside a function, UNO is local to the function, but not stored on the stack (as already mentioned). These means only one instance of it exists which may or may not be the behavior you want if the function is called recursively. The 'const' means the programmer has promised the compiler that he/she will not try to change its value.

“static const” is supposed to be a good replacement for #define, at least at global scope.
Whether it will actually result in allocated memory depends on exactly how it is used.
On a samd board, if it does allocate memory, then it will end up in flash memory, but on a avr it will be in RAM (if allocated.)

I have a practical example in mind form samd21g18a.h:

#define SERCOM0           ((Sercom   *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */
#define SERCOM1           ((Sercom   *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */
#define SERCOM2           ((Sercom   *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */
#define SERCOM3           ((Sercom   *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */
#define SERCOM4           ((Sercom   *)0x42001800U) /**< \brief (SERCOM4) APB Base Address */
#define SERCOM5           ((Sercom   *)0x42001C00U) /**< \brief (SERCOM5) APB Base Address */
#define SERCOM_INST_NUM   6                         /**< \brief (SERCOM) Number of instances */
#define SERCOM_INSTS      { SERCOM0, SERCOM1, SERCOM2, SERCOM3, SERCOM4, SERCOM5 } /**< \brief (SERCOM) Instances List */

I want to get the address base for a sercom numbered from 0 to 5. So here is a solution:

Sercom *getSercom ( uint8_t iSercom )
{
   static const Sercom *sercoms[SERCOM_INST_NUM] SERCOM_INSTS;
   return sercoms[iSercom];
}

I guess that is good for SAMD21. The numbers will go in ROM. But on AVR, it would be better to omit the static and const.

For example:

void setup() {
  static const char xxxx[] = "this is a test of static const";
  static const char yyyy[] = "this is a different string";
  Serial.print(xxxx);
  Serial.print(yyyy[6]);
}

Will allocate memory for yyyy, but not for xxxx:

[color=purple][b]avr-nm -SC /tmp/OldArduBuild/*.elf | grep " d "[/b][/color]
00800100 00000012 d vtable for HardwareSerial
00800112 0000001f d setup::xxxx