> The article also says that global variables will kill you, putting variables on the stack will kill you but doesn't say where it is safe to put variables. I can't imagine the heap is any better, that a garbage collector isn't going to pause and kill you, etc.
Function-scope static or file-scope static variables are the best place for variables in an embedded system written in C. They don't pollute the shared namespace, nor do they require allocation and de-allocation.
In an Arduino program, for example, you might have something like this, with a sketch.ino file:
#include <stdint.h>
#include "MyFile.h"
uint32_t Bad_Global_Variable;
// This doesn't conflict with same name in MyFile.cpp
static uint8_t state = 1;
void setup() {
setup_myFile();
state = 0;
}
void loop() {
loop_myFile();
}
a MyFile.h header:
#ifndef _MY_FILE_H_
#define _MY_FILE_H_
#include <stdint.h>
void setup_myFile(void);
void loop_myFile(void);
#endif // End include guard
and a MyFile.cpp library:
#include "MyFile.h"
static uint32_t MyFileScopeVariable = 0;
// This doesn't conflict with same name in sketch.ino
static uint8_t state = 0;
void setup_myFile(void)
{
MyFileScopeVariable = 1;
// Can't access or have conflicts with myFunctionScopeVariable here
state = 1;
}
void loop_myFile(void)
{
static uint32_t myFunctionScopeVariable = 0;
MyFileScopeVariable++;
myFunctionScopeVariable++;
}
Statically allocated variables are definitely the only the way to go.
Statically allocated global variables are easy and available, suitable for small embedded systems written by one person or a small group of collaborators who can be expected to know about every variable in the program or at least to be able to refactor their code if it collides with an existing name. Adding a prefix to your statically allocated global variables (eg. 'mf_state' for a global variable in the MyFile library above) is another way to reduce collisions, but isn't compiler-enforced.
Statically allocated file-scope or function-scope variables are a best practice in an automotive ECU scale projects, and can reduce issues if you've got lots of vendors each contributing code and not a lot of visibility between projects.