2015-09-06 14 views
10

Po odkryciu niespójności między MSVC i GCC (prawdopodobnie też klang) w kompilacji i powiązaniu tego samego kodu, stałem się ciekawy, czy ten program faktycznie się kompiluje i łączy, a tym samym jest to błąd w MSVC (który zgłasza błąd linkera) czy powinienem napisać to inaczej. Program składa się z 3 plików:Czy następujący program powinien się kompilować zgodnie ze standardem?

CH

template <typename T> 
struct A 
{ 
    void func() {}; 
}; 

template <> 
void A<int>::func(); 

A.cpp:

#include "C.h" 
int main() 
{ 
    A<int> x; 
    x.func(); 
} 

B.cpp:

#include "C.h" 
template <> 
void A<int>::func() 
{ 
} 

Uzyskany błąd jest łącznikiem z MSVC:

A.obj: error LNK2019: nierozwiązanych zewnętrznych symbolu "public: void __thiscall A :: func (void)"

Więc w zasadzie to nie zdecyduje się utworzyć symbol z definicji umieszczonej w B.cpp. To, co sprawia, że ​​mocno podejrzewam, że jest to błąd, polega na tym, że przeniesienie niespecjalistycznej definicji z definicji struct, a nawet umieszczenie jej powyżej deklaracji specjalizacyjnej sprawia, że ​​program linnkingowy jest udany, ale chciałbym być tego pewien.

Moje pytanie brzmi - czy ten program powinien być skompilowany i połączony bez błędów przez zgodny kompilator/linker?

+0

Wygląda jak błąd dla mnie. Czy korzystasz z najnowszej (2015) wersji MSVC? –

+0

@MatsPetersson Tak, 2015. – Predelnik

+0

Twój kod kompiluje się dobrze z klang ++.To trochę dziwne, ponieważ zasadniczo podajesz dwie definicje dla 'func' - nie jestem wystarczającym językiem-prawnikiem aby powiedzieć, czy to jest poprawne czy nie (myślę, że to jest) –

Odpowiedz

1

od standardu:

© ISO/IEC N4527 14.6.4.1 Punkt instancji [temp.point] 1 dla specjalizacji szablonu funkcja, funkcja członek szablonu specjalizacji, lub specjalizacji dotyczący funkcja składowa lub statyczny element danych szablonu klasy , jeśli specjalizacja jest niejawnie utworzona, ponieważ odwołuje się do niej z poziomu innej specjalizacji szablonu, a kontekst, z którego się odwołuje, zależy od parametru szablonu, , od momentu utworzenia instancji Specjalizacja to poi nt of tworzenie instancji specjalizującej się w powłoce. W przeciwnym razie punkt tworzenia instancji dla takiej specjalizacji następuje bezpośrednio po deklaracji zakresu lub definicji zakresu przestrzeni nazw o wartości , która odnosi się do specjalizacji.

W tym przypadku myślę to oznacza co C.h gdzie występuje „deklaracja zakres”. W takim przypadku Twój kod powinien łączyć się ze standardowym, zgodnym łańcuchem narzędzi. Mogę źle to zinterpretować ...

-2

Nienazwane przestrzenie nazw mają wewnętrzne powiązania. Ponieważ specjalizacja szablonu znajduje się w nienazwanej przestrzeni nazw, ma również wewnętrzne powiązania.

Aby rozwiązać problem, umieść szablon w nazwanym obszarze nazw lub określ specjalizację jako "zewnętrzną".

+0

"bezimienny obszar nazw" nie oznacza tego, co według ciebie oznacza. –

Powiązane problemy