Static is a keyword with many meanings, and in this particular case, it means not global (paraphrasing)

It means that each .cpp file has its own copy of the variable. Thus, when you initialize in main.cpp, it is initialized ONLY in main.cpp. The other files have it still uninitialized.

First thing to fix this would be to remove the keyword static. That would cause the "Multiple definitions issue". To fix this you should define the variable in a .cpp file and just extern declare it in a header file.


Edit: You are just allocating memory to it, doesnt count as initialization. You need to initialize the memory to 0 after allocation.

You can use new int[128]() instead of your more verbose malloc syntax, and this would perform initialization as well? Or you could take the easy road (thats what its there for) and use std::vector


The key is this:

static int *pieces;

You said you put that in your header. This is not the way to export a symbol. Any file that includes the header will get its own static version of an uninitialised pointer called pieces.

Instead, you put this in your header:

extern int *pieces;

extern int init_pieces();

And in the source file, you do this:

static const size_t num_pieces = 128;

int *pieces = 0;

int init_pieces()
{
    pieces = malloc( num_pieces * sizeof(int) );
    return pieces != NULL;
}

Now when you include your header, your source file will know to get pieces from somewhere else, and will wait for the linker to work out where. I also suggested an 'init' function for the array. I did not put a 'release' function in, however.

Note this is all C, not C++. If you're using C++ you should really use new or better still, use a vector.

Also, when using statics in C++, be mindful of this: C++ static initialization order


In C++17 standard, you can use inline specifier instead of static. For variables this means every object unit will have a copy of the variable, but linker will choose only one of them. Or, as stated on cppreference:

An inline function or inline variable (since C++17) has the following properties:

1) There may be more than one definition of an inline function or variable (since C++17) in the program as long as each definition appears in a different translation unit and (for non-static inline functions and variables (since C++17)) all definitions are identical. For example, an inline function or an inline variable (since C++17) may be defined in a header file that is #include'd in multiple source files.

2) The definition of an inline function or variable (since C++17) must be present in the translation unit where it is accessed (not necessarily before the point of access).

3) An inline function or variable (since C++17) with external linkage (e.g. not declared static) has the following additional properties:

1) It must be declared inline in every translation unit.

2) It has the same address in every translation unit.

Supported in (source):

  • MSVC since version 19.12 (VS 2017 15.5)
  • GCC 7
  • Clang 3.9
  • ICC 18.0

In this case, it means you can replace

static int *pieces;

with

inline int *pieces;