Ich verstehe, dass C ++ - Compiler nicht miteinander kompatibel sind. Allerdings konnte ich zu diesem Thema insbesondere für C nichts finden. Ich weiß, dass der C-Standard den Compilern viel Raum lässt, um Dinge zu implementieren, wie sie es für richtig halten: Beispielsweise ist die Größe und Ausrichtung der meisten (alle?) Datentypen implementierungsdefiniert, abgesehen von einigen minimalen Garantien. Daher können zwei Compiler (oder zwei Versionen desselben Compilers) in zahlreichen Details nicht übereinstimmen.
Habe ich Recht, wenn ich denke, dass es keine Garantie dafür gibt, dass zwei mit verschiedenen Compilern kompilierte Objektdateien tatsächlich richtig verknüpft werden? Beispielsweise könnte die Größe von Zeigern in einer Objektdatei 32 Bit und in der anderen 64 Bit betragen. Aber wenn ja, warum werden C-Bibliotheken manchmal in vorkompilierter Form verteilt? Gibt es eine Erwartung, dass ich denselben Compiler verwenden werde (z. B. gcc), oder einen De-facto- Standard, der verwendet wird, um die Binärkompatibilität sicherzustellen? Und wie stellen andere Sprachen mit einer Fremdsprachenschnittstelle sicher, dass die Dinge beim Verknüpfen mit C-Objektdateien richtig ausgerichtet sind?
Antworten:
Die allgemeine Antwort lautet Nein, C-Sprach-Compiler sind nicht miteinander kompatibel. Der C-Sprachstandard definiert keinerlei binäre Interoperabilität, und die meisten Compiler-Autoren versuchen es nicht einmal.
Ich muss das qualifizieren. Die von einem C-Compiler ausgegebenen Objekte müssen mit Laufzeitbibliotheken verknüpft werden, um entweder eine ausführbare oder eine zur Laufzeit verknüpfbare Bibliothek zu erstellen. Obwohl die von der C-Laufzeitbibliothek bereitgestellten sichtbaren Funktionen kompatibel sein sollten, gibt es auch nicht sichtbare Funktionen, die nur für die Implementierung gelten und die Interoperabilität verhindern.
Diese mangelnde Kompatibilität erstreckt sich auch auf verschiedene Versionen desselben Compilers. Im Allgemeinen können Programme und Bibliotheken, die mit älteren und neueren Versionen eines Compilers kompiliert wurden, nicht miteinander verknüpft werden, und Programme, die mit MSVC kompiliert wurden, können nicht mit denen verknüpft werden, die von GCC kompiliert wurden.
Es gibt eine spezifische und sehr nützliche Ausnahme. Jede Plattform bietet eine dynamische Verknüpfung von ABI (Application Binary Interface) und jedes Programm in jeder Sprache, die diesem ABI entsprechen kann, ist kompatibel. Daher ist es im Allgemeinen möglich, eine DLL (unter Windows) mit MSVC (oder etwas anderem) zu erstellen und sie aus einem Programm aufzurufen, das von einer anderen Version von MSVC oder von GCC kompiliert wurde, und umgekehrt.
Unter Windows gibt es zwei weitere ABIs: COM- und .NET-Assemblys, die eine Vielzahl von Sprachen umfassen. Interoperabilität ist also definitiv möglich, aber nicht kompatibel.
Der Grad der Inkompatibilität kann leicht durch Vergleichen der Linker-Maps festgestellt werden. Für die Verwendung mit GNU
ld -M
, für die Verwendung mit MSVClink /map
. Studieren Sie die beiden generierten Dateien. Beide enthalten Namen, die Sie erkennen, z. B. printf und main, obwohl die Namen (abhängig von den Optionen) wahrscheinlich auf verschiedene Weise entstellt werden. Sie haben auch völlig andere Namen, von denen Sie viele nicht erkennen. Damit Objektdateien, die von verschiedenen Compilern erstellt wurden, kompatibel sind, müssen sie sich auf all diese Namen einigen, und das tun sie niemals. Das können nicht einmal verschiedene Versionen desselben Compilers.quelle
Was Sie suchen, wird als ABI (Application Binary Interface) bezeichnet.
Die C-Sprache definiert kein ABI. In diesem Sinne gibt es in der Tat keine Garantie dafür, dass C-Dateien, die mit verschiedenen Compilern kompiliert wurden, miteinander funktionieren.
Andererseits definiert das Betriebssystem auf den meisten Plattformen einen ABI für die Schnittstelle mit ihm, und alle Compiler, die auf diese Betriebssystem- und Prozessorfamilie abzielen, verwenden denselben ABI auch für die Schnittstelle mit Nicht-Betriebssystemkomponenten. In der Praxis können C-Objekte, die von verschiedenen Compilern erstellt wurden, miteinander arbeiten.
quelle