Eine meiner Hauptbeschwerden über C ++ ist, wie schwierig es in der Praxis ist, Standardbibliotheksobjekte außerhalb der dynamischen Bibliotheksgrenzen (dll / so) zu übergeben.
Die Standardbibliothek enthält häufig nur Header. Das ist großartig, um einige großartige Optimierungen durchzuführen. Bei DLLs werden sie jedoch häufig mit unterschiedlichen Compilereinstellungen erstellt, die sich auf die interne Struktur / den Code eines Standardbibliothekscontainers auswirken können. Beispielsweise kann in MSVC eine DLL mit aktiviertem Iterator-Debug erstellt werden, während eine andere mit deaktiviertem Iterator erstellt wird. Diese beiden DLLs können Probleme beim Weitergeben von Standardcontainern verursachen. Wenn ich std::string
in meiner Benutzeroberfläche offenlege, kann ich nicht garantieren, dass der Code, für den der Client verwendet std::string
wird, genau mit dem meiner Bibliothek übereinstimmt std::string
.
Dies führt dazu, dass Probleme, Kopfschmerzen usw. nur schwer behoben werden können. Sie steuern entweder die Compilereinstellungen in Ihrer Organisation streng, um diese Probleme zu vermeiden, oder Sie verwenden eine einfachere C-Schnittstelle, die diese Probleme nicht aufweist. Oder geben Sie Ihren Clients die erwarteten Compilereinstellungen an, die sie verwenden sollen (was schade ist, wenn eine andere Bibliothek andere Compilereinstellungen angibt).
Meine Frage ist, ob C ++ 11 versucht hat, diese Probleme zu lösen.
DLL
s. Zwischendurch hatSO
es immer prima geklappt.Antworten:
Sie haben Recht, dass in einer öffentlichen C ++ - API alles, was als STL bezeichnet wird, dh alles, was aus einer Bibliothek eines Drittanbieters stammt, am besten vermieden wird. Sie möchten auch die lange Liste von Regeln unter http://www.ros.org/reps/rep-0009.html#definition befolgen , um ABI-Brüche zu verhindern, die das Programmieren öffentlicher C ++ - APIs zu einer lästigen Aufgabe machen.
Und die Antwort in Bezug auf C ++ 11 ist nein, dieser Standard berührt das nicht. Interessanter ist, warum nicht? Die Antwort liegt darin, dass C ++ 17 das sehr berührt, und damit C ++ - Module implementiert werden können, müssen exportierte Vorlagen funktionieren, und dafür benötigen wir einen LLVM-Compiler wie clang, der den vollständigen AST auf die CD und dann ausgeben kann Führen Sie aufruferabhängige Suchvorgänge durch, um die vielen Fälle von ODR-Verstößen in einem großen C ++ - Projekt zu behandeln - das übrigens viel GCC- und ELF-Code enthält.
Zuletzt sehe ich eine Menge MSVC-Hass- und Pro-GCC-Kommentare. Diese sind sehr falsch informiert - GCC auf ELF ist grundsätzlich und unwiederbringlich nicht in der Lage, gültigen und korrekten C ++ - Code zu erstellen. Die Gründe dafür sind zahlreich und zahlreich, aber ich werde schnell ein Fallbeispiel anführen: GCC unter ELF kann keine sicheren Python-Erweiterungen erzeugen, die mit Boost.Python geschrieben wurden, wobei mehr als eine auf Boost.Python basierende Erweiterung in Python geladen wird. Das liegt daran, dass ELF mit seiner globalen C-Symboltabelle nicht in der Lage ist, ODR-Verstöße, die zu Fehlern führen, zu verhindern, wohingegen PE und MachO sowie die vorgeschlagene C ++ - Modulspezifikation Symboltabellen pro Modul verwenden - was im Übrigen auch erheblich schnellere Prozessinitialisierungszeiten bedeutet. Und es gibt noch viel mehr Probleme: Sehen Sie sich einen StackOverflow an, auf den ich kürzlich geantwortet habehttps://stackoverflow.com/questions/14268736/symbol-visibility-exceptions-runtime-error/14364055#14364055 zum Beispiel, wenn C ++ - Ausnahmewürfe auf ELF unwiederbringlich grundlegend beschädigt sind.
Letzter Punkt: In Bezug auf das Interagieren verschiedener STLs ist dies ein großes Problem für viele große Unternehmensbenutzer, die versuchen, Bibliotheken von Drittanbietern zu mischen, die eng in eine STL-Implementierung integriert sind. Die einzige Lösung ist ein neuer Mechanismus für C ++, mit dem STL-Interop behandelt werden kann, und während C ++ gerade dabei ist, können Sie auch das Interop des Compilers reparieren, damit Sie beispielsweise kompilierte MSVC-, GCC- und Clang-Objektdateien mischen können und alles funktioniert . Ich würde mir die C ++ 17-Bemühungen ansehen und sehen, was sich in den nächsten Jahren dort abspielt - ich wäre überrascht, wenn nichts passiert.
quelle
Die Spezifikation hatte dieses Problem nie. Das liegt daran, dass es ein Konzept mit der Bezeichnung "Eine Definitionsregel" gibt, das vorschreibt, dass jedes Symbol im laufenden Prozess genau eine Definition hat.
Windows-DLLs verletzen diese Anforderung. Deshalb gibt es all diese Probleme. Es liegt also an Microsoft, das Problem zu beheben, nicht am C ++ - Standardisierungsausschuss. Unix hatte dieses Problem nie, da gemeinsam genutzte Bibliotheken dort anders funktionieren und standardmäßig einer Definitionsregel entsprechen (Sie können es explizit brechen, aber Sie tun es offensichtlich nur, wenn Sie wissen, dass Sie es sich leisten können und die wenigen zusätzlichen Zyklen ausmerzen müssen).
Windows-DLLs verstoßen gegen eine Definitionsregel, weil:
Unix, das ELF-Formatexporte verwendet, importiert implizit alle exportierten Symbole, um das erste Problem zu vermeiden, und unterscheidet erst nach einer statischen Verbindungszeit zwischen statisch und dynamisch aufgelösten Symbolen, um das zweite zu vermeiden.
Das andere Problem sind Compiler-Flags. Dieses Problem tritt bei jedem Programm auf, das aus mehreren Kompilierungseinheiten besteht. Dynamische Bibliotheken müssen nicht beteiligt sein. Unter Windows ist es jedoch viel schlimmer. Unter Unix spielt es keine Rolle, ob Sie statisch oder dynamisch verknüpfen, niemand verknüpft die Standardlaufzeit statisch (unter Linux ist dies möglicherweise sogar illegal) und es gibt keine spezielle Debug-Laufzeit, sodass ein Build gut genug ist. Die Art und Weise, wie Microsoft statisches und dynamisches Verknüpfen, Debugging und Release-Laufzeit sowie einige andere Optionen implementierte, führte jedoch zu einer kombinatorischen Explosion der benötigten Bibliotheksvarianten. Wieder ein Problem mit der Plattform und nicht mit der C ++ - Sprache.
quelle
Nein.
Es wird viel daran gearbeitet, das Headersystem zu ersetzen, eine Funktion, die als Module bezeichnet wird und einen Einfluss darauf haben könnte, aber sicherlich keinen großen.
quelle