I\'m in the process of moving code written to be compiled for one chip onto another chip.
One issue that\'s come up is a multitude of multiple definition errors. Some of
The error goes away if I declare it as extern and define it in the cpp file,
The issue is that even when include guarded etc. the variable gets created once in each compilation unit - but since it is global it is pointing to same variable.
To overcome this is issue you need to either create it in anon. namespace
Something.h
namespace {
int foo = 0;
}
Or, use the static keyword
Something.h
static int foo = 0;
Both will create a different variable in each compilation unit.
in C++ 17 you can resolve this issue by inline variables. Inline variables avoid the duplication of variables defined in header files. The variables defined in the header file will be treated as initialized in a cpp file. They won't be duplicated. So can be directly included the code.
If you declare your variable in the header file:
#ifndef GLOBAL_H
#define GLOBAL_H
int foo = 0;
#endif
In every include of your header file or translation unit, a new instance of your integer is created. As you mentioned, to avoid this, you need to declare the item as "extern" in the header file and initialize it in the implementation file:
// .h
extern int foo;
// .cpp
int foo = 0
A more C++ way to do that can be something like this:
#ifndef GLOBAL_H
#define GLOBAL_H
struct Global {
static int foo;
};
#endif
And in your cpp file:
#include "variables.h"
int Global::foo = 0;
C++17 fixes this problem with inline variables, so you can do:
#ifndef GLOBAL_H
#define GLOBAL_H
inline int foo = 0;
#endif
See How do inline variables work? for more information.