Portabilität der C-Sprache

10

Wie genau wird die Portabilität einer Sprache wie C bestimmt? Ich habe gelernt, dass Compiler ISA-spezifisch sind. Wenn dies zutrifft, wie ist C portabel? Oder ist nur der in C geschriebene Quellcode portabel, nicht aber die ausführbaren Dateien? Sind die ausführbaren Dateien, die ISA-spezifisch für Beispielanwendungen für x86 ist, nicht von den Anwendungen für Apple getrennt (vorausgesetzt, Apple verwendet den Motorola / PowerPC-Mikroprozessor)?

KawaiKx
quelle

Antworten:

26

Ist es so, dass nur der in C geschriebene Quellcode portabel ist, nicht die ausführbaren Dateien?

Richtig. Manche Leute nennen es einmal schreiben, überall kompilieren.

http://en.wikipedia.org/wiki/Write_once,_compile_anywhere .

Die andere Alternative ist einmal schreiben, überall ausführen. Java ist ein gutes Beispiel dafür.

http://en.wikipedia.org/wiki/Write_once,_run_anywhere

Und obwohl Sie eine teilweise plattformübergreifende Portabilität erreichen können, sollten Sie niemals erwarten, dass Ihr Code ohne Änderungen überall ausgeführt wird.

adolfojp
quelle
C-Quellcode, der nicht auf verschiedene Compiler, ISAs oder Betriebssysteme portiert werden kann, ohne einiges an mehrsprachigen Shennanigans. Einfache Dinge wie die Größe und Ausrichtung von Standardtypen sind in C nicht Standard, daher kann die Portierung von Software, die Daten mit anderen Instanzen von sich selbst austauscht, eine große Herausforderung sein. In GNU Autoconf / Automake finden Sie ein (möglicherweise verschleiertes) Beispiel für die Reifen, durch die C-Programmierer springen, um Portabilität zu erhalten.
Tim Williscroft
3
@ TimWilliscroft: Portabilitätsprobleme werden normalerweise durch nicht standardmäßige Bibliotheken und schlechte Programmierpraktiken verursacht. und werden nicht durch C oder seine Standardbibliotheken verursacht. Ein einfaches Beispiel wäre die Verwendung einer nicht standardmäßigen GCC-Erweiterung oder die fehlerhafte Serialisierung / De-Serialisierung von Daten für E / A.
Brendan
6

Es ist nicht nur ISA-spezifisch. Zum Beispiel fragen Sie:

Anwendungen für x86 sind von den Anwendungen für Apple getrennt?

Ja, obwohl Apple x86-Hardware verwendet. C-Binärdateien sind architektur- und betriebssystemspezifisch.

vartec
quelle
1
@ Steven314: Dein Kommentar ist eine Tangente. Es hat nichts damit zu tun, ob Hardware Standard ist oder nicht, und alles damit, dass OS X ein anderes Binärformat (Mach-O) hat als beispielsweise Linux (normalerweise ELF).
Mipadi
@Steve: EFI vs BIOS sind nur für das Booten und die Interna des Betriebssystems von Bedeutung. Die Hardwarearchitektur, bei der es sich um den CPU-Befehlssatz handelt, ist dieselbe, da es sich um dieselbe CPU handelt.
Vartec
Kommentare gelöscht, hauptsächlich, weil ich das Mac-Ding überhaupt nicht hätte einbinden sollen. Meine Erwähnung von ABI (Application Binary Interface) und Anrufkonventionen ist möglicherweise immer noch relevant (ein dritter Punkt, der zu "Architektur und Betriebssystem" hinzugefügt werden muss). Sie sind nicht hardwarerelevant, außer dass ABIs in der Regel für bestimmte Architekturen (z. B. verfügbare Register) entwickelt wurden, sie sind jedoch für die binäre Portabilität relevant. Dies ist kein Dateiformatproblem - ELF wird unter Windows und Linux (von gcc) verwendet, aber Sie können wahrscheinlich keine Objektdatei von einer zur anderen übertragen.
Steve314
@vartec Sie sagten, C-Binärdateien seien auch betriebssystemspezifisch. Liegt es daran, dass O / S selbst ISA-spezifisch ist, sodass C-Binärdateien indirekt O / S-spezifisch werden?
KawaiKx
@Saurabh - Alle nativen ausführbaren Dateien sind betriebssystemspezifisch, da das Betriebssystem das Dateiformat angibt. Außerdem muss eine C-Standardbibliothek viele Funktionen durch Aufrufen des Betriebssystems implementieren. Selbst wenn das Dateiformat standardisiert wäre, könnte der Code selbst nicht auf einem anderen Betriebssystem ausgeführt werden. Dies ist Standard für Sprachen, die mit nativem Code kompiliert werden, im Gegensatz zu Code für virtuelle Maschinen wie JVM (Java Virtual Machine). Es ist möglich, C für eine virtuelle Maschine zu kompilieren, aber ich habe nie etwas getan, von dem ich weiß. LLVM kommt am nächsten, ist jedoch als Compiler-Back-End gedacht - nicht als Compile-Umgebung, die einmal ausgeführt werden kann.
Steve314
5

Ist es so, dass nur der in C geschriebene Quellcode portabel ist, nicht die ausführbaren Dateien?

Genau. Sie müssen Ihr C-Programm auf jeder Plattform neu kompilieren. C-Compiler generieren Maschinencode, der nur in sehr begrenztem Umfang zwischen Maschinen mit derselben Prozessor- / Speicherarchitektur und demselben Betriebssystem portierbar ist. Aus diesem Grund sehen Sie verschiedene Binärdistributionen von Multiplattform-Apps (z. B. Browsern) wie "Linux 64-Bit Intel" oder "Mac OS X 32-Bit PowerPC" (OK, die letzte ist nur eine Illustration, ich weiß, Apple hat gewechselt vor ein paar Jahren bei Intel :-).

Péter Török
quelle
3

Der größte Teil der Frage wurde beantwortet, aber ich möchte hinzufügen, dass Haltbarkeit eine andere Sache ist, die Sie möglicherweise berücksichtigen müssen.

Zum Beispiel kann JAVA einmal geschrieben und auf jeder Plattform ausgeführt werden, auf der sich die VM befindet (heute heißt sie "Laufzeitumgebung"). Ein weiterer Vorteil ist, dass Sie Java 1.1-Code von 1995 auf Ihrem 2011er Computer ausführen können. Dies ist nicht möglich, wenn Ihr Code auf i386 kompiliert wurde und Sie versuchen, ihn auf Ihrer AMD64-Architektur auszuführen.

Sie erhalten auch die Verbesserungen der virtuellen Maschine selbst.

Dann würde ich sagen, dass im Allgemeinen von den am wenigsten portablen zu den portableren Sprachen übergegangen wird: Assembler, kompilierte Sprache auf niedriger Ebene wie C, dann C ++, dann interpretierte Sprachen oder solche, die in einer virtuellen Maschine ausgeführt werden.

Ich bin nicht wirklich ein Java-Verteidiger, zumindest nicht für die Sprache oder die Community, aber es ist der richtige Weg, wenn Sie nach Portabilität und dem geringsten Leistungsverlust im Vergleich zu C suchen.

tiktak
quelle
3

Gute Antworten zum Schreiben einmal kompilieren überall.

Aufgrund seiner Beliebtheit und der hohen Wahrscheinlichkeit, dass ein C-Compiler für zukünftige Zielplattformen verfügbar ist, denken die Leute gerne an C als tragbare Sprache. Ein weiterer Faktor ist die Standardbibliothek, die bei allgemeinen Programmieraufgaben plattformunabhängig hilft.

Ich würde also sagen, dass die Portabilität einer Sprache bestimmt wird durch:

  1. Standardisierungsgrad.
  2. Verfügbarkeit von Compilern für verschiedene Plattformen / Architekturen.
  3. Tiefe und Breite der tragbaren Bibliotheken.

Realistisch gesehen erfordert jedoch fast jede komplexe C-Anwendung aufgrund von Hardware- oder Betriebssystemabhängigkeiten einige Arbeit, um auf eine neue Plattform umzusteigen. Dieser Vorgang wird als Portierung bezeichnet.

Guy Sirton
quelle
3

"Portabilität" hat mehrere Bedeutungen. In Bezug auf C bedeutet dies Folgendes:

  • Für C wurden Compiler für eine Vielzahl von Hardware- und Betriebssystemplattformen implementiert, was Anfang der 70er Jahre eine große Sache war.

  • Es gibt einen allgemein vereinbarten Standard für die Sprache selbst, im Gegensatz zu jeder Compiler-Implementierung, die eine etwas andere Variante der Sprache erkennt (wiederum eine große Sache, als C zum ersten Mal entworfen wurde, da es mehrere Varianten von Sprachen wie Pascal und BASIC gab das war nicht allgemein anerkannt);

  • Aufgrund dieses Standards erzeugt konformer Code beim Kompilieren auf verschiedenen Plattformen dasselbe Verhalten.

Der Quellcode ist portabel, aber für jedes Ziel muss eine neue Binärdatei generiert werden.

Beachten Sie jedoch, dass die C-Quelle selten "trivial" portabel ist. Bei den meisten Anwendungen müssen Sie über die Definitionen des Sprachstandards hinausgehen und Erweiterungen verwenden, die nur für eine bestimmte Plattform gelten. In der Praxis ist der Quellcode daher nicht zu 100% portabel.

Beachten Sie jedoch, dass C der Implementierung ziemlich viel überlässt. Die genauen Größen der verschiedenen Datentypen, das Verhalten beim Überlauf usw. hängen von der Implementierung ab. Der Standard enthält die Mindestanforderungen , denen eine Implementierung entsprechen muss, aber die Implementierung kann diese Grenzen überschreiten.

John Bode
quelle
0

Was auch immer ISA ist, C ist nicht ISA-spezifisch. Ich gehe davon aus, dass Sie sich nicht auf den mittlerweile veralteten Steckplatz für PC-Erweiterungskarten beziehen.

Es gibt standardkonforme C-Compiler für sehr viele Plattformen. Solange Sie in Ihrem Quellcode vollständig standarddefinierte Sprachfunktionen verwenden, sollten Sie diese auf jedem C-Compiler für jede Plattform kompilieren können.

Ein Problem ist jedoch, dass der C-Standard viele Verhaltensweisen von Features entweder als implementierungsdefinierte oder als undefiniertes Verhalten belässt. Dies geschieht, um die C-Sprache allgemeiner für die Programmierung auf niedriger Ebene zu machen und Fälle zu vermeiden, in denen ein genau definiertes Verhalten nicht mit dem übereinstimmt, was die Hardware auf einer bestimmten Plattform unterstützt. Es macht es jedoch etwas schwieriger, tragbare Programme zu schreiben.

Im Gegensatz zu einigen Sprachen wird C nicht mit einer riesigen Bibliothek geliefert, wie sie Java oder C # bieten. Sie können sehr tragbare Bibliotheken dazu bringen, fast alles zu tun, aber Sie müssen einige Arbeiten ausführen, um sie zu erstellen und sie zur Zusammenarbeit zu bringen.

C hat natürlich eine Standardbibliothek, aber ihr Umfang ist im Vergleich zu Java, C #, Python usw. relativ begrenzt.

Steve314
quelle
4
ISA = Befehlssatzarchitektur alias Hardwarearchitektur
vartec