I'm going to guess that you are using Visual C++, which has a rather horrible language extension, as described in "Microsoft Extensions to C and C++":
Out of Class Definition of static const Integral (or enum) Members
Under the standard (/Za
), you need to make an out-of-class definition for data members. For example,
class CMyClass {
static const int max = 5;
int m_array[max];
}
...
const int CMyClass::max; // out of class definition
Under /Ze
, the out-of-class definition is optional for static, const integral, and const enum data members. Only integrals and enums that are static and const can have initializers inside a class; the initializing expression must be a const expression.
To avoid errors when an out-of-class definition is provided (when the out-of-class definition is provided in a header file and the header file is included in multiple source files), you should use selectany. For example:
__declspec(selectany) const int CMyClass::max = 5;
The /Ze
flag is enabled by default. You have to explicitly use the /Za
flag if you don't want the language extensions.
The code as written compiles and links as-is without error using g++ 4.5.2, Clang 3.0, and Visual C++ 2010 with the /Za
flag set.
Removing the definition from the .cpp file resolves the issue if you want to compile with Visual C++, but then it won't work with other compilers (or with /Za
) if you try to use the data member. For a portable workaround, you can use a conditional compilation block that checks to see whether the extensions are enabled:
#ifndef _MSC_EXTENSIONS
const int A::b;
#endif