Static constant class member declaration

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 *1 line 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

9.4.2 Static data members
§3...
The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.


Try defining these members:

static const unsigned int FOOBAR = 10;
static const unsigned int BARFOO = 20;

Outside the class declaration.

Foo::FOOBAR = 10;
Foo::BARFOO = 20;
链接地址: http://www.djcxy.com/p/63738.html

上一篇: 在.NET中使用PayPal沙盒的'安全标题无效'

下一篇: 静态常量类成员声明