it-swarm.com.de

Warum bietet C Sprachbindungen an, bei denen C ++ zu kurz kommt?

Ich habe mich kürzlich gefragt , wann ich C über C++ verwenden soll und umgekehrt? Zum Glück hat jemand hat mich schon geschlagen und obwohl es Es dauerte eine Weile, bis ich alle Antworten und Kommentare zu dieser Frage verdauen konnte.

Ein Punkt in diesem Beitrag wird jedoch immer wieder angesprochen, ohne dass ein Beispiel, eine Überprüfung oder eine Erklärung vorliegt:

"C-Code ist gut, wenn Sie mehrere Sprachbindungen für Ihre Bibliothek haben möchten"

Das ist eine Paraphrase. Ich sollte beachten, dass mehrere Leute darauf hinweisen, dass in C++ mehrere Sprachbindungen möglich sind (über einige extern -Funktionen), aber wenn Sie diesen Beitrag vollständig lesen, ist es ziemlich offensichtlich, dass C ideal für Portabilität ist/Sprachbindung. Meine Frage ist: warum?

Kann jemand bitte konkrete Gründe nennen, warum das Schreiben von Bibliotheken in C einfachere Bindungen und/oder Portabilität in anderen Sprachen ermöglicht?

60
smeeb

C hat eine viel, viel einfachere Schnittstelle, und seine Regeln zum Konvertieren einer Quellcode-Schnittstelle in eine binäre Schnittstelle sind so einfach, dass das Generieren externer Schnittstellen zum Binden auf etablierte Weise erfolgt. C++ hingegen hat eine unglaublich komplizierte Oberfläche, und die Regeln für die ABI-Bindung sind weder formal noch in der Praxis standardisiert. Dies bedeutet, dass so ziemlich jeder Compiler für jede Sprache für jede Plattform an eine externe C-Schnittstelle gebunden werden kann und genau weiß, was zu erwarten ist. Für eine C++ - Schnittstelle ist dies jedoch im Wesentlichen unmöglich, da sich die Regeln je nach Compiler, welcher Version und welcher ändern Plattform, mit der der C++ - Code erstellt wurde.

In C gibt es auch keine Standardregeln für die Implementierung von Binärsprachen, aber es ist eine Größenordnung einfacher und in der Praxis verwenden Compiler dieselben Regeln. Ein weiterer Grund, der das Debuggen von C++ - Code erschwert, ist die oben erwähnte komplizierte Grammatik, da Debugger häufig nicht mit vielen Sprachfunktionen umgehen können (Platzieren von Haltepunkten in Vorlagen, Analysieren von Zeigerbefehlen in Datenanzeigefenstern usw.).

Das Fehlen einer Standard-ABI (Application Binary Interface) hat eine weitere Konsequenz: Der Versand von C++ - Schnittstellen an andere Teams/Kunden ist unpraktisch, da der Benutzercode nur funktioniert, wenn er mit denselben Tools und Build-Optionen kompiliert wurde. Wir haben bereits eine andere Ursache für dieses Problem gesehen - die Instabilität der binären Schnittstellen aufgrund der fehlenden Kapselung der Kompilierungszeit.

- Defektes C++

69
Mason Wheeler

Wenn Sie versuchen, mit einem Sprecher einer anderen Sprache zu kommunizieren, ist Pidgin einfacher als Shakespeare-Englisch.

Die Konzepte von C - Funktionsaufrufe, Zeiger, NULL-terminierte Zeichenfolgen - sind sehr einfach, sodass andere Sprachen sie leicht gut genug implementieren können, um C-Funktionen aufzurufen. Aus historischen Gründen sind viele andere Sprachen in C implementiert, was das Aufrufen von C-Funktionen noch einfacher macht.

C++ fügt eine Menge Dinge hinzu - Klassen mit Vererbung und vtables und Zugriffsmodifikatoren; Ausnahmen, bei denen der Stapel abgewickelt und der Kontrollfluss geändert wird; Vorlagen. All dies erschwert es anderen Sprachen, C++ - Bindungen zu verwenden: Im besten Fall muss mehr "Kleber" oder Interoperabilitätscode implementiert werden, und im schlimmsten Fall werden die Konzepte nicht direkt übersetzt (aufgrund von Unterschieden in den Klassenmodellen, Ausnahmebehandlung, usw.). Insbesondere für Vorlagen erfordert die einfache Verwendung (Instanziierung) normalerweise einen Kompilierungsschritt mit einem C++ - Compiler, was die Verwendung aus anderen Umgebungen erheblich erschwert .

Nach alledem ist es möglich, die Schwierigkeit, Bindungen aus einer C++ - Bibliothek in eine andere Sprache bereitzustellen, zu überschätzen:

  • C++ - Bindungen können genauso kompatibel sein wie C, wenn Sie bereit sind, daran zu arbeiten. Wie @DeadMG hervorhebt, unterstützt C++ extern "C", sodass Sie Sprachbindungen im C-Stil (mit der Einfachheit und Kompatibilität von C-Bindungen) aus einer C++ - Bibliothek exportieren können (mit der Einschränkung, dass Sie keine C++ - spezifischen Funktionen verfügbar machen können).
  • Ein weiterer häufiger Einwand gegen C++ - Sprachbindungen ist die mangelnde ABI-Stabilität für C++, aber auch dies ist übertrieben. C++ - ABIs sind weniger standardisiert als C ABIs, es gibt jedoch Standards und De-facto-Standards (das Itanium C++ ABI, das auch verwendet wird nter OS X ; GCCs De-facto-Standard für Linux). Windows ist schlechter, aber selbst unter Windows sollte es gut funktionieren, innerhalb einer Visual C++ - Version zu bleiben.
32
Josh Kelley

C ist eine der ältesten Sprachen, die es noch gibt. Das ABI ist einfach und praktisch jedes heute noch verwendete Betriebssystem wurde darin geschrieben . Während einige dieser Betriebssysteme möglicherweise Dinge hinzugefügt haben, z. in C # /. NET oder was auch immer oben, unten sind sie sehr stark von C durchdrungen.

Das heißt, um die vom Betriebssystem bereitgestellten Funktionen nutzen zu können , benötigte praktisch jede Programmiersprache a Möglichkeit, trotzdem mit C-Bibliotheken zu kommunizieren . Perl, Java, C++, sie alle nativ bieten Möglichkeiten, "C zu sprechen", weil sie es mussten, wenn sie nicht jedes einzelne Rad neu erfinden wollten es gibt.

Dies macht C zum Latein der Programmiersprachen. (Wie viele Jahre Internet vor dieser Metapher muss "das Englisch der Programmiersprachen" sein?)


Wenn Sie Ihre Bibliothek in C schreiben, erhalten Sie (offensichtlich) kostenlos eine C-kompatible Schnittstelle. Wenn Sie Ihre Bibliothek in C++ schreiben, erhalten Sie können C-Bindungen über extern "C" - Deklarationen, wie Sie erwähnt haben.

Jedoch, Sie können diese Bindungen nur für Funktionen erhalten, die in C ausgedrückt werden können .

Ihre Bibliotheks-API kann also nicht ...

  • vorlagen,
  • klassen,
  • ausnahmen,
  • alle Funktionen , die oder Objekte zurückgeben .

Ein einfaches Beispiel: Sie müssten Ihre exportierten Funktionen dazu bringen, und zurückzugeben Arrays ([]) anstelle von std::vector (oder std::string).

Sie wären also nicht nur nicht in der Lage, den Kunden Ihrer Bibliothek eines der guten Dinge zu bieten, die C++ zu bieten hat, sondern müssten auch zu zusätzlichen gehen. Bemühungen, Ihre Bibliotheks-API von C++ in "C-kompatibel" (extern "C") zu "übersetzen".

Aus diesem Grund könnte der Punkt gemacht werden, dass C die bessere Wahl für die Implementierung einer Bibliothek ist. Persönlich denke ich, dass die Vorteile von C++ immer noch den notwendigen Aufwand für eine extern "C" - API überwiegen, aber das bin nur ich.

21
DevSolar

Lassen Sie die Details weg, die andere Antworten bereits liefern:

Der Grund, warum so viele Sprachen eine C-Bindung bereitstellen, ist, dass alle * nix- und Windows-Betriebssysteme den größten Teil ihrer Betriebssystem-API über eine C-Schnittstelle verfügbar machen. Die Sprachimplementierung muss also bereits mit C verbunden sein, um auf den Haupt-Oses ausgeführt werden zu können. Daher ist es unkompliziert, auch die direkte Kommunikation mit einer beliebigen C-Schnittstelle aus der Sprache selbst anzubieten.

6
Martin Ba

Es gibt keinen Grund. Wenn die Semantik, die Sie ausdrücken möchten, grundsätzlich C-kompatibel ist und nicht so etwas wie Vorlagen, gibt es keinen Grund, warum Sie einfacher binden können, wenn die Implementierung in C geschrieben ist. Tatsächlich ist es ziemlich per Definition = dass eine C-Schnittstelle von jeder Implementierung ausgefüllt werden kann, die den Binärvertrag erfüllt - einschließlich einer Implementierung in einer anderen Sprache. Es gibt andere Sprachen als C++, die C-Binärverträge implementieren können, die auf diese Weise funktionieren können.

Worauf es wirklich ankommt, sind Menschen, die keine neuen Sprachen oder Ideen lernen möchten, die tatsächlich nützliche Semantik oder Funktionen haben, und verzweifelt versuchen, einen Grund zu finden, um in der Dinosaurier-Ära zu bleiben.

5
DeadMG

Bei der Verbindung mit einer anderen Sprache gibt es zwei Hauptachsen:

  • die Konzepte, die die Schnittstelle übertragen kann: nur Werte? Verweise? Generika?
  • wie die Schnittstelle in "Binärdateien" (ABI genannt) implementiert ist

C hat in diesen beiden Bereichen einen Vorteil gegenüber C++:

  • C hat nur meist einfache Konzepte, die in fast jeder anderen Sprache vorkommen1
  • Die ABI von C-Binärdateien wird vom Betriebssystem festgelegt2

Nun, warum haben die meisten Sprachen ähnliche Konzepte wie C, weil es entweder "einfach" oder "vorbestehend" ist; Es spielt jedoch keine Rolle, der Punkt ist, dass sie es tun.

Im Gegenteil, C++ hat komplexe Konzepte, und der ABI wird von jedem Compiler festgelegt (obwohl viele den Itanimum-ABI einhalten, außer unter Windows ...). Es gab tatsächlich einen Vorschlag von Herb Sutter, Betriebssysteme einen C++ - ABI (pro Betriebssystem) reparieren zu lassen, um dieses Problem teilweise zu beheben. Man sollte auch beachten, dass ein C++ FFI möglich ist, D versucht es3.

1 Außer Variadics (...), die sind nicht einfach

2 Hat C einen Standard-ABI?

3 Schnittstelle von D zu Legacy C++ - Code

2
Matthieu M.

Grundsätzlich kommt es auf die ABI-Standardisierung an. Während weder C noch C++ einen standardisierten ABI haben, den andere Sprachen für die Schnittstelle zwischen geschriebenen Binärdateien verwenden können, ist C zu einem De-facto-Standard geworden, jeder weiß es und jeder andere kann dieselben einfachen Regeln verwenden, die die Sprache in Bezug auf hat Typen und Funktionsaufrufe.

C++ könnte einen Standard-ABI haben, aber Stroustrup hat gesagt, dass er keinen Bedarf dafür sieht. Er sagt auch, dass es schwierig sein würde, einen Konsens von Compiler-Autoren zu erzielen (obwohl ich bezweifle, dass - das C++ - Standardkomitee einen ABI herausgeben würde, der den bestehenden ähnlich ist, und Compiler-Autoren einfach die nächste Version ihrer Compiler ändern würden, die gelegentlich nicht mit Binärdateien kompatibel sind ohnehin mit alten Versionen ihrer Compiler erstellt - ich erinnere mich, dass ich einige Bibliotheken mit einem neuen Sun-Compiler neu kompiliert habe und festgestellt habe, dass sie mit den alten nicht funktionieren).

Sie werden feststellen, dass einige Unternehmen auf die Verwendung eines Standard-ABI umgestellt haben. Microsoft hat diesen Prozess bereits in den 90er Jahren mit COM gestartet. Heute haben sie diesen in den WinRT-ABI verfeinert (nicht zu verwechseln mit dem anderen WinRT, auf den verwiesen wird zu einem Typ von Tabellenbetriebssystem), mit dem in C # geschriebene Programme mit in C oder C++ geschriebenen Bibliotheken kommunizieren können (dh die Microsoft-eigene Betriebssystemschicht wird in C++ geschrieben, mit WinRT verfügbar gemacht und von C # -Anwendungen verwendet, wenn sie eine Betriebssystem-Laufzeitroutine aufrufen).

Es gibt nicht viel, was jemand tun kann, wenn nicht eine Normungsbehörde diese Situation behebt und behebt. Microsoft sieht den Wert offensichtlich darin und hat Schritte unternommen, um ihn für die Plattform aufzulösen.

Die Antwort lautet also wirklich C nicht Sprachbindungen bereitstellen. Es kommt vor, dass niemand zugehört hat und sie trotzdem konsumiert.

0
gbjbaanb