in Foo.h:
class Foo
{
public:
Foo();
static const unsigned int FOOBAR = 10;
static const unsigned int BARFOO = 20;
private:
unsigned int m_FooBar;
bool m_Bar;
void Bar();
};
in Foo.cpp:
Foo::Foo()
: m_FooBar(FOOBAR), // this works
m_Bar(false)
{
}
void Foo::Bar()
{
//m_FooBar = m_Bar ? FOOBAR : BARFOO; // linker fails *1
m_FooBar = FOOBAR; // ok
}
I’m compiling with GCC 4.5.3. Is there any reason why the linker would fail when line *1 is uncommented?
Foo.o: In function 'Foo::Bar' (name unmangled):
Foo.cpp: undefined reference to `Foo::FOOBAR'
Foo.cpp: undefined reference to `Foo::BARFOO'
Tried with VC2005, 2008, 2010 and CB2010. They all compiled and linked fine. Why does GCC fail in this case?
Given the answer here, why doesn’t the other popular compilers fail like GCC? One way or another, it has to be a bug, either for GCC or the other popular compilers. Or is there a more reasonable explanation?
Formally, the header only declares the static constants, and they also have to be defined (at least in C++03). However, if you only use their values, you most often get away with this.
In C++11 this is more formally specified as requiring a definition when the static is “odr-used”. The
*1line is an example of this. The triadic operator tries to form a reference to the values, and the compiler (or linker actually) realizes that it cannot.The C++11 standard says