Ich habe kürzlich ziemlich viel Zeit damit verbracht, ein Problem aufzuspüren, das durch das Kompilieren einer Bibliothek mit -D_GLIBCXX_DEBUG
verursacht wurde (was libstdc ++ anweist, eine Debug-Version der Standardbibliothek mit zusätzlichen Prüfungen zu verwenden), aber das kompilieren Client-Programm ohne. Dies führte zu einem ABI-Kompatibilitätsproblem.
Gibt es eine Möglichkeit, solche Probleme mit GCC automatisch zu erkennen? Visual Studio bietet das detect_mismatch
pragma , das meiner Meinung nach diesem Zweck gedient hätte, aber ich ' Ich bin mir keiner GCC-Äquivalenz bewusst. GCC tut etwas mit der Einbettung eines Symbolnamens (zB GLIBCXX_3.4.9
), und ich kann mir Schemata vorstellen, die wegen eines undefinierten Symbols einen Verknüpfungsfehler verursachen, wenn ein entsprechendes Symbol (zB mylib_debug_stl
) nicht vorhanden wäre, sondern die einzigen Möglichkeiten kann daran denken, eine Verwendung dieses Symbols wirklich hacky zu bekommen.
Alternativ, wie vermeiden andere Leute dieses Problem? Erstellen Sie die geprüfte Version der Bibliothek unter einem anderen Name oder etwas in der Art?
Gibt es eine Möglichkeit, solche Probleme mit GCC automatisch zu erkennen?
Nur der Linker kann erkennen, ob Sie inkompatiblen Code und nicht den Compiler verknüpfen.
Der alternative Linker gold
kann einige Probleme mit der Option --detect-odr-violations
erkennen.
Alternativ, wie vermeiden andere Leute dieses Problem? Erstellen Sie die überprüfte Version der Bibliothek unter einem anderen Name oder etwas?
Ich stelle nur sicher, dass ich alles neu aufbaut, wenn ich den Debug-Modus benutzen will. Ich glaube nicht, dass ich jemals eine Bibliothek behalten wollte, die mit dem Debug-Modus gebaut wurde. Es ist zum Debuggen gedacht, nicht für den normalen Gebrauch.
Ich benutze selten -D_GLIBCXX_DEBUG
auf jeden Fall, ich mache eher etwas wie:
Dann ändere ich die Präprozessor-Bedingung, wenn ich einen Debug-Modus-Vektor für diese spezifische Klasse verwenden möchte, ohne jeden Container im Programm zu beeinflussen. Da die Änderung darin besteht, in die Datei zu schreiben (und somit ihren Zeitstempel zu aktualisieren), wird alles, was von diesem Header abhängt, von make
neu erstellt, und es gibt zwei verschiedene Typen, std::vector<int>
und __gnu_debug::vector<int>
, die unterschiedliche Symbole haben und können bin nicht durch den Linker verwirrt.
Wenn Sie _GLIBCXX_DEBUG
definieren, werden nicht alle Abhängigkeiten neu erstellt und die Definition von std::vector
global geändert, statt bestimmte Container in einen anderen Typ mit einem anderen Namen zu ändern, __gnu_debug::vector
Es stellte sich heraus, dassdurch das Kompilieren einer Bibliothek mit -D_GLIBCXX_DEBUG verursacht wurde (wodurch libstdc ++ angewiesen wurde, eine Debug-Version der Standardbibliothek mit zusätzlichen Prüfungen zu verwenden), aber das Client-Programm ohne.
kompiliert wurde
Es ist ein explizites libsdc++
Debugging-Modus Designziel, um eine solche Konfiguration zu unterstützen, und ich bezweifle, dass das die tatsächliche Ursache Ihres Problems war.
Das Problem ist möglicherweise verschwunden, nachdem Sie die Bibliothek ohne -D_GLIBCXX_DEBUG
neu erstellt haben, aber das beweist nicht, dass die ABI
Inkompatibilität die Hauptursache war.