2015-03-27 6 views
7

Ich sehe eine ganze Reihe von Fragen wie Apple Mach-O Linker (Id) Error und Undefined symbols in cryptopp at IOS 64-bit project. Das Problem wird in der Regel wie beschrieben:Woher kommt das __1-Symbol, wenn LLVMs libC++ verwendet wird?

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) 

Das Problem reduziert oft Mischen/Matching -stdlib=libc++ (LLVM C++ Laufzeit) und -stdlib=libstdc++ (GNU C++ Laufzeit). Die LLVM C++ Laufzeit (libc++) hat ein __1 Dekorationssymbol, aber die GNU C++ Laufzeit libstdc++fehlt das __1 Symbol in seinem Namen. Es verursacht Linker-Probleme für Symbole, die scheinbar denselben Namen haben (wie std::string).

Woher kommt das __1 Symbol, wenn LLVMs libC++ verwendet wird?

Warum wurde das Problem nicht mit einem Namespace gnu Namespace und ein llvm gelöst?


Hier ist eine weitere Frage: libc++ - stop std renaming to std::__1?. Aber es vermisst den Punkt, dass eine Umbenennung nicht stattfindet.

+1

Es ist ein Inline-Namespace, der libC++ für Versionierung verwendet. – Praetorian

Antwort

4

Es ist von C++ 11 inlined Namespaces

libC++ etwas wie

hat
namespace std { 
    inline namespace __1 { 
     .... 

mehr bei What are inline namespaces for?

+0

Danke @Severin. Das ist ein interessanter Link. Also * wenn * ich einen C++ 11-Compiler verwendet habe, würden die Probleme mit 'std :: string' und' std :: __ 1 :: string' wegfallen, weil der Compiler den Inline-Namespace verstehen würde? Oder das Problem würde verschwinden, wenn ich '-std = C++ 03 'verwenden würde, weil Inline-Namespaces nicht verwendet würden? (Bis jetzt habe ich Leuten gesagt, alles mit der LLVM-Laufzeit oder der GNU-Laufzeit zu kompilieren). – jww

+2

@jww Ich glaube, dass beide Compiler (GCC und Clang) inlined namspaces verstehen. Problem ist mit Deklaration vs Definition. Wenn Sie libC++ - Header verwenden, erhalten Sie Deklarationen, die mit dem Präfix 'std :: __ 1 ::' ausgewählt wurden, etwas wie 'std :: __ 1 :: string' usw. Wenn Sie GNU libstdC++ - Header verwenden, werden Sie hole deklaration 'std :: string' etc. Aber dann musst du Definitionen entweder aus libstdC++. a/.so oder aus libC++. a/.so holen. Aufgrund der Tatsache, dass jede Bibliothek mit eigenen Headern kompiliert wird, tragen Definitionen auch das gleiche Präfix. Fortsetzung folgt ... –

+2

Wenn Sie Deklarationen aus libC++ - Headern (mit std :: __ 1 :: - Präfix) auswählen, aber versuchen, Definitionen aus libstdC++ (mit std :: - Präfix) zu verwenden, erhalten Sie linker error - definitions don nicht viel. Gut, denke ich, Debugging könnte ein Albtraum sein. So würde ich sagen, wenn Sie GNU toolchain verwenden, Link gegen libstdC++, wenn clang - Link gegen libC++ –