2015-06-26 16 views
7

Mam następujący kod (uproszczony), który kompiluje grzywny w gcc, ale daje błąd w VS:VS2013 - static const już zdefiniowane

// main.cpp 
#include "test.h" 
int main() { 
    return 0; 
} 

// test.h 
#pragma once 
class Test { 
    static const int TEST = 3; 
}; 

// test.cpp 
#include "test.h" 
const int Test::TEST; 

Błąd:

main.obj : error LNK2005: "private: static int const Test::TEST" ([email protected]@@0HB) already defined in test.obj 

jest to Błąd VS lub gcc niepoprawnie pozwala mi jawnie zdefiniować statyczny element const?

Aktualizacja: Znalazłem to w C++ Standard (9.4.2.3):

If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression (5.20). A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. — end note ] 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.

Aktualizacja # 2: znalazł bug report, który twierdzi, że jest ona ustalana w następnej wersji.

+0

Co się stanie, jeśli usuniesz 'const int Test :: TEST;' z twojego 'test.cpp', czy gcc skompiluje kod? – ixSci

+0

Wygląda na to, że działa, ale pracuję z kodem, który jawnie definiuje te linie i nie chce ich edytować, ponieważ spowoduje to ponowne złamanie przy następnej aktualizacji svn. – riv

+0

Dzięki, chciałem tylko wiedzieć, czy gcc ma błąd innego rodzaju. Sądziłem, że wymaga to wyraźnego zdefiniowania stałej we wszystkich przypadkach. Ale jeśli tak nie jest, to tylko błąd w MSVC. – ixSci

Odpowiedz

2

Dokładnie tak jak powiedziałeś, był to MSVC bug. Kod kompiluje się i działa idealnie w Visual Studio 2015 RC z domyślnymi opcjami projektu.

enter image description here

Kompilator uważa "statyczne const Int próby = 3"; i "const int Test :: TEST;" są dwiema różnymi definicjami tej samej zmiennej. Aby rozwiązać ten problem w swojej wersji można spróbować ustawić statyczną wartość zmiennej w pliku .cpp:

// test.h 
#pragma once 
class Test { 
    static const int TEST; 
}; 

// test.cpp 
#include "test.h" 
const int Test::TEST = 3; 
1

Z Microsoft Extensions to C and C++ włączona, kompilator automatycznie generuje out-of-klasy definicji. Niektóre wersje kompilatora są prawdopodobnie błędne i wykonują tę automatyczną definicję, nawet jeśli zdefiniowałeś ją ręcznie (na przykład podczas pisania kodu przenośnego).

Możesz wyłączyć rozszerzenia lub sprawdzić makro _MSC_EXTENSIONS. Jest zdefiniowany, gdy ustawiona jest opcja/Ze. Na przykład:

#ifndef _MSC_EXTENSIONS 
    const int MyClass::MyStaticMember; 
#endif