Kevin217 Kevin217 - 24 days ago 5
C++ Question

Multiple definition when using namespace in header file

I'm trying to define a global namespace in a header file

global.h
.

...
namespace g {
const int g_0 = 0;
const int g_1 = 1;
}
...


When JUST
#include "global.h"
in other .cpp file, compiler gives an error

multiple definition of g::g_0
multiple definition of g::g_1


If I try to use
g_0
and
g_1
in other .cpp files, for example.

int g_0_copy = g::g_0;
int g_1_copy = g::g_1;


It throws an error saying:

ISO C++ forbids in-class initialization of non-const static member...


Is there something special when using namespace to declare global variable?
(I have to use c++98 in this case)

Answer

If all of your globals are const, you most likely merely need include guards.

#ifndef   GLOBAL_H
#define   GLOBAL_H

...
namespace g {
   const int g_0 = 0;
   const int g_1 = 1;
}
...

#endif // GLOBAL_H

const global variables have internal linkage unless explicitly declared extern, so they won't cause linking errors as long as they're only defined once per translation unit. Each translation unit will have its own copy of each global constant, which the compiler may or may not optimise out if possible.


If some of your globals aren't const, however, it gets a bit more complex.

#ifndef   GLOBAL_H
#define   GLOBAL_H

...
namespace g {
   const int g_0 = 0;
   const int g_1 = 1;

   int g_2 = 2; // Oh, boy.
}
...

#endif // GLOBAL_H

As this variable has external linkage by default, it will cause a linking error due to multiple translation units containing different variables named g_2. The solution here is to declare the variables extern in the header, and place their actual definitions in a source file.

// global.h
#ifndef   GLOBAL_H
#define   GLOBAL_H

...
namespace g {
   const int g_0 = 0;
   const int g_1 = 1;

   extern int g_2; // Oh, boy.
}
...

#endif // GLOBAL_H

// ---

// global.cpp
namespace g {
   int g_2 = 2;
}

That said, as SergeyA pointed out in the comments, the error message you got indicates that there's more to this:

ISO C++ forbids in-class initialization of non-const static member...

I can't say anything about this, without knowing what code is causing it.

Comments