Mike
Mike

Reputation: 1

Embedded C: manager for global variables

I want to encapsulate global variables in a single "data-manager-module". Access is only possible with functions to avoid all the ugly global variable problems ... So the content is completely hidden from the users. Are there any existing concepts? How could such an implementation look like? How should the values stored in the "data-manager-module"?

Upvotes: 0

Views: 679

Answers (3)

Lundin
Lundin

Reputation: 214810

A "data manager module" doesn't make any sense. Implementing one would merely be sweeping away a fundamentally poor program design underneath the carpet, hiding it instead of actually cleaning it up. The main problem with globals is not user-abuse, but that they create tight couplings between modules in your project, making it hard to read and maintain, and also increases the chance of bugs "escalating" outside the module where the bug was located.

Every datum in your program belongs to a certain module, where a "module" consists of a h file and a corresponding c file. Call it module or class or ADT or whatever you like. Common sense and OO design both dictate that the variables need to be declared in the module where they actually belong, period.

You can either do so by declaring the variable at file scope static and then implement setter/getter functions. This is "poor man's private encapsulation" and not thread-safe, but for embedded systems it will work just fine in most cases. This is the embedded industry de facto standard of declaring such variables.

Or alternatively and more advanced, you can do true private encapsulation by declaring a struct as incomplete type in a h file, and define it in the C file. This is sometimes called "opaque type" and gives true encapsulation on object basis, meaning that you can declare multiple instances of the class. Opaque type can also be used to implement inheritance (though in rather burdensome ways).

Upvotes: 6

technosaurus
technosaurus

Reputation: 7812

You can keep all variables in a single source inside a struct with getters and setters

static struct all_globals{
  long long myll;
  /* ... */
} all_globals; /* Not _really_ global*/

long long getmyll(void){
  return all_globals.myll;
}

long long setmyll(long long value){
  return all_globals.myll = value;
}

similarly, you could use an internal header file that is not exported to the user API, then strip symbols from the resulting binary/library

/* globals.c */
struct all_globals{
  long long myll;
  /* ... */
} all_globals; /* Not _really_ global*/

/* globals.h */
#define getmyll() all_globals.myll
#define setmyll(value) all_globals.myll = (value)

This will still be technically visible to the end user with enough effort, but allows you to distinguish globals and keep them together.

Upvotes: 0

SF.
SF.

Reputation: 14079

Declare and define all the variables in a header file that is included into the manager's .c file but not into its .h That way they will be only visible for the manager's functions.

Upvotes: 0

Related Questions