2012-09-19 12 views
7

in foo.h:Statische Konstante Klasse Memberdeklaration

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 
} 

ich mit GCC 4.5.3 bin kompilieren. Gibt es einen Grund, warum der Linker fehlschlägt, wenn Zeile * 1 unkommentiert ist?

Foo.o: In function 'Foo::Bar' (name unmangled): 
Foo.cpp: undefined reference to `Foo::FOOBAR' 
Foo.cpp: undefined reference to `Foo::BARFOO' 

Mit VC2005, 2008, 2010 und CB2010 versucht. Sie alle zusammengestellt und gut verbunden. Warum scheitert GCC in diesem Fall?

Angesichts der answer here, warum nicht die anderen populären Compiler wie GCC fehlschlagen? So oder so, es muss ein Bug sein, entweder für GCC oder die anderen populären Compiler. Oder gibt es eine vernünftigere Erklärung?

+3

Hmm ... Es kompiliert in VS2010 gut. – Mysticial

+0

Kompiliert und verbindet in CB2010 und VS2005 zu –

+1

@Mysticial Frage ist über GCC obwohl. und ich kann den Linker-Fehler bestätigen. –

Antwort

4

Formal ist der Kopf erklärt nur die statischen Konstanten, und sie haben auch (zumindest in C++ 03) definiert werden. Wenn Sie jedoch nur ihre Werte verwenden, kommen Sie meistens damit durch.

In C++ 11 ist dies formaler definiert als eine Definition erfordern, wenn die statische "odr-used" ist. Die *1-Linie ist ein Beispiel dafür. Der triadische Operator versucht, einen Verweis auf die Werte zu bilden, und der Compiler (oder Linker tatsächlich) erkennt, dass dies nicht möglich ist.


Der C++ 11-Standard sagt

9.4.2 Statische Datenelemente
§3 ...
Das Mitglied wird noch in einem Namespace Umfang, wenn es definiert werden wird odr-used (3.2) im Programm verwendet und die Namespace-Bereichsdefinition darf nicht einen Initialisierer enthalten.

+0

aber in C++ 03 Integer statischen Konstanten sind in Ordnung, wenn sie in der Kopfzeile deklariert und definiert, wie in den Fragen –

+0

Sie sind in Ordnung, wenn Sie nur ihre Werte verwenden. Der Triadic-Operator erzeugt einen Verweis auf einen der beiden Werte, was nicht möglich ist, wenn sie nicht definiert sind. Sie erhalten einen ähnlichen Effekt, wenn Sie versuchen, einen der Werte anhand einer Funktion zu übergeben. –

+0

Warum also nicht die anderen bekannten Compiler? Wenn der triadische Operator das tut, sollte es nicht auch auf VC2010 scheitern? –

0

versuchen, diese Elemente zu definieren:

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

Außerhalb der Klassendeklaration.

Foo::FOOBAR = 10; 
Foo::BARFOO = 20; 
Verwandte Themen