Global variables

Revision as of 10:29, 10 February 2020 by Vegard (talk | contribs) (add note)
Jump to navigation Jump to search

Global variables are discouraged by a lot of people for various different reasons [1]. One objection is that it becomes harder to reason about (and test) functions because they have a "hidden" input (i.e. the global state).

I think global variables have their place, and are honestly not that different from, say, instance variables used by methods. One way to simply make it clear that global state is used in the code would be to provide a couple of wrappers for defining and declaring the use of global variables, respectively:


#define DEFINE_GLOBAL(type, name) __thread typeof(type) global_##name
#define USE_GLOBAL(name) typeof(global_##name) &name = global_##name


#include <cstdio>


void foo()

    printf("x = %d\n", x);

#if 0 // doesn't work, since x is undeclared
void bar()
    printf("x = %d\n", x);

// complex type declarations also work:
DEFINE_GLOBAL(void (*)(int), fn);

If you want to be able to override the global for a function (e.g. for testing using mock data, without actually modifying the global), one could even put the declaration in the parameter list:

void baz(USE_GLOBAL(x))
    printf("x = %d\n", x);

This function can be called either as


in which case it will use the actual global variable, or

int value = 12;

but here, the argument may not be a temporary expression.

Also note that any such globals declared in the parameter list must be declared after all the other parameters, since they are default-initialized to the global!