2015-03-27 16 views
7

Widzę sporo pytań, takich jak Apple Mach-O Linker (Id) Error i Undefined symbols in cryptopp at IOS 64-bit project. Problem ten jest zazwyczaj opisywane jako:Skąd pochodzi symbol __1 podczas używania biblioteki libC++ LLVM?

Undefined symbols for architecture i386: 
    "std::__1::basic_ostream<char, std::__1::char_traits<char> >::flush()", referenced from: 
     cv::gpu::error(char const*, char const*, int, char const*) in opencv2(gpumat.o) 

problem często zmniejsza do mieszania/dopasowania -stdlib=libc++ (llvm C++ wykonania) i -stdlib=libstdc++ (GNU C++ wykonania). Środowisko wykonawcze LLVM C++ (libc++) ma symbol dekoracji __1, ale w środowisku wykonawczym GNU C++ libstdc++ brakuje w jego nazwie symbolu . Powoduje to problemy z linkerem dla symboli, które wydają się mieć tę samą nazwę (jak std::string).

Skąd pochodzi symbol podczas korzystania z biblioteki libC++ LLVM?

Dlaczego problem nie rozwiązany z gnu nazw i nazw llvm?


Oto powiązany pytanie: libc++ - stop std renaming to std::__1?. Ale to nie trafia w punkt, w którym zmiana nazwy nie występuje.

+1

To nazw inline że libC++ używa do tworzenia wersji. – Praetorian

Odpowiedz

4

To z C++ 11 inlined nazw

libC++ ma coś podobnego

namespace std { 
    inline namespace __1 { 
     .... 

więcej w What are inline namespaces for?

+0

Dzięki @Severin. To interesujący link. Więc * jeśli * użyłem kompilatora C++ 11, problemy z 'std :: string' i' std :: __ 1 :: string' znikną, ponieważ kompilator zrozumie wbudowaną przestrzeń nazw? Lub problem zniknie, jeśli użyłbym '-std = C++ 03', ponieważ wstawiane przestrzenie nazw nie byłyby używane? (Do tej pory mówiłem ludziom, żeby kompilowali wszystko za pomocą środowiska wykonawczego LLVM lub środowiska wykonawczego GNU). – jww

+2

@jww Wierzę, że oba kompilatory (GCC i clang) rozumieją wbudowane namspacje. Problem dotyczy deklaracji a definicji. Jeśli używasz nagłówków libC++, otrzymasz deklaracje wybrane przez prefiks 'std :: __ 1 ::', coś jak 'std :: __ 1 :: string' itd. Jeśli używasz nagłówka GNU libstdC++, będziesz get deklaracja 'std :: string' itd. Ale musisz wybrać definicje z biblioteki libstdC++. a/.so lub z biblioteki libC++. a/.so. Ponieważ każda biblioteka jest skompilowana z własnymi nagłówkami, definicje zawierają również ten sam prefiks. Aby kontynuować ... –

+2

Tak więc, jeśli wybierzesz deklaracje z nagłówków libC++ (z std :: __ 1 :: prefiks), ale spróbuj użyć definicji z libstdC++ (z prefiksem std ::), otrzymujesz błąd linkera - definicje nie dużo. Dobrze, myślę, że debugowanie może być koszmarem. Powiedziałbym, że jeśli używasz GNU toolchain, link do libstdC++, jeśli clang - link przeciwko libC++ –

Powiązane problemy