Does anybody know the how, why, or if static member declarations are exempt from the preprocessor? Consider this situation
Class A is declared in a header file, and has a protected static member 'x'. x is declared in the header file, but within the preprocessor block. E.G.
#ifndef foo
#define foo
class A {
protected:
static int x;
};
int A::x = 0;
#endif
Then, other classes which derive from A include the same A header file, but also their own B, C, D, etc, as necessary. They compile fine, but when I link it all togehter, I get a 'duplicate symbol' errors for A for every module that included the A header file. If i move the static declaration out of the .h and into the .cpp, everything links as necessary.
Are these static declarations exempt from the preprocessor? Since there's a possibility the other, inhereted modules get compiled first, does the declaration of the protected member *have* to be in the module of the top-level class? Is there any sort of rule or spec that goes into this? It's with MSVC.
Always another 'gotcha' with C++, that's for sure
-r
Hi redskull,
Just move "int A::x = 0;" to the module with class A implementation. This line will actually allocate memory for x.
The same error you can get with normal variables. "extern int x;" in a header is ok, but with assigned value is not ok (if two or more modules are including that header).
Optionally you could keep "int A::x = 0;" in your header, but protenced by another #ifdef:
#ifndef foo
#define foo
class A {
protected:
static int x;
};
#ifdef A_cpp // begin a.cpp private defines
int A::x = 0;
#endif
#endif
file a.cpp
#define A_cpp
#include "a.h"
any other file:
#include "a.h"
What akane said. The way you're doing it, each translation module that includes that header is creating a memory location for x when it hits
int A::X = 0;
When you try to link them all together, they all have their own locations set aside for the same symbol, and nastiness ensues. As a general rule, make sure that you only declare things in header files, never assign them.