head.h
#pragma once
namespace foo
{
int bar;
int funct1();
}
head.cpp
#include \"head.h\"
int foo::funct1()
{
This foo
namespace-level bar
declaration:
namespace foo
{
int bar;
}
is actually a definition.
To make it a declaration, mark the bar
as extern
in head.h:
namespace foo
{
extern int bar;
}
Then define it in head.cpp:
int foo::bar = 0;
How is it being defined multiple times?
It is defined once in head.cpp and once in main.cpp. That is a total of two times. This violates the one definition rule, which states that there may only be one definition for every variable.
int bar;
This is a definition of a variable. You've included it into two translation units.
A variable can be declared without definition in an extern declaration:
extern int bar;
Replace the definition with such declaration, and put the definition into exactly one translation unit.
head.h
is included in both main.cpp and head.cpp.
So the variable is defined twice.
Possible Solution: make it inline. The "extern" solutions are also good, although older in approach.
namespace foo
{
inline int bar;
}
The header head.h
is included in two compilation units head.cpp
and main.cpp
. So the variable bar
is defined twice. You could declare the variable without its definition the following way
#pragma once
namespace foo
{
extern int bar;
int funct1();
}
and then define it in some cpp module.
I am not redefining anything. I am literally just assigning 1 to the variable
You're redefining the variable!
head.cpp
has one via #include "head.h"
, and main.cpp
has one via #include "head.h"
.
You need to merely declare it (unusual but not too strange) in the header:
extern int bar;
…then define it in one translation unit. This is just like what you do with static
class members (albeit with slightly different syntax).
Since C++17, you may do this by instead plopping the inline keyword on to your definition.
Alternatively, avoid mutable globals…
Do carefully note that foo
is not a class, but a namespace. When you declare a free variable in the header file:
int bar;
And then #include this header file multiple times (into different CPP files, causing multiple translation unit compilations), you'd get a linker error. Everyone knows it.
And, you'd add extern
attribute at the declaration, and define the variable elsewhere in one of the CPP/C file.
Putting a global variable into a namespace is nothing but giving the global variable a different name. Think if foo::bar
as foo__NS__bar
, and hence you must add extern
in the header and define foo::bar
at some locatoin.
Note that this is different from a non-static member variable of a class. A class variable doesn't need to be defined/declared this way since the class is a type. Each instantiated variable of class-type would have a separate copy of the variable.
Further to that, when you add a static
variable in the class, you are giving that logically global variable another name. Thence, you must have that static-variable defined one of the CPP file.