A couple years ago I learned, that global variables are bad and should be avoided. But I know they are sometimes unavoidable, at least in an embedded system with interrupts. What do you think is the most elegant way to work with them?
In my projects I have a file called globals.h
where I define all my global variables:
global.h
#ifndef GLOBALS_H
#define GLOBALS_H
extern int16_t gVariable1;
extern int16_t gVariable2;
….
#endif
In my main project file I declare all global variables:
main.c
/*
***********************************************************************
* global variables *
***********************************************************************
*/
int16_t gVariable1 = 0;
int16_t gVariable2 = 0;
int16_t main (void)
{
gVariable1 = 6;
// do other stuff
}
And now I include globals.h
in every other file of the project, which needs access to a global variable.
That works fine, but is there a more elegant way to handle that?
I am not sure that global variables are bad in all cases, but you really need to work hard to have very few of them (otherwise, your code in unreadable). For example <stdio.h>
has stdout
, and it won't be better if it was replaced by some FILE*get_standard_output(void);
getter function.
As a rule of thumb, avoid having more than 4 or 5 global variables in your entire program (recall the magical number seven as a hint on our cognitive limitations).
However, you could pack (cleverly and with good taste, to keep your code readable) several related global variables into a single one of struct
type. With your example, that could mean in your globals.h
:
struct globalstate_st { int16_t v1, v2; };
then
extern struct globalstate_st gs;
and you would use gs.v1
instead of gVariable1
; if you compile with optimizations, the performance of using gs.v1
is equivalent to using gVariable1
.
BTW, if you have a multi-threaded program, you generally should protect global data with some mutex (or some other kind of synchronization or atomicity). Consider reading this pthread tutorial.