Java wird oft für seine erstaunliche Portabilität gelobt, die vermutlich auf die JVM zurückzuführen ist. Meine Frage ist, was verhindert, dass C kompiliert / interpretiert / JIT'ed wird. Wenn ja, kann C auch einmal geschrieben werden und auf jedem Gerät funktionieren, das Sie haben. Dies ist jedoch kein beliebter Mechanismus zur Verarbeitung eines C-Programms.
Was sind die Nachteile der Verarbeitung von C auf diese Weise, und was sind die Vorteile der Verarbeitung von Java auf diese Weise und der Nichtkompilierung in Maschinencode, abgesehen von der Portabilität natürlich?
Antworten:
C ist das, was ich als Mittelsprache bezeichnen würde. Sein Zweck ist es, als "Assembler auf sehr hoher Ebene" zu dienen, weshalb es so gut als Compiler-Ziel funktioniert und die Portabilität so gut unterstützt.
In der Vergangenheit wurden Dolmetscher normalerweise im Zusammenhang mit Methodenaufrufen mit Hochsprachen verwendet . In seiner einfachsten Form analysiert ein Interpreter lediglich jedes Schlüsselwort in der Ausgangssprache zusammen mit den zugehörigen Token und konvertiert diese in Methodenaufrufe und Parameter. In der Praxis konvertieren die meisten Dolmetscher die Ausgangssprache in eine Zwischendarstellung, und diese Darstellung wird interpretiert.
Was hindert C daran, interpretiert oder Jitted zu werden? Nichts. Aber das ist nicht Cs Daseinsberechtigung.
quelle
Zunächst ist anzumerken, dass Suns JVM in C geschrieben wurde. C ist eine sehr beliebte Sprache, wenn Portabilität erforderlich ist.
Die C- Sprache ist portabel, obwohl dies bei vielen C- Programmen nicht der Fall ist. Dies liegt daran, dass C dem Programmierer nicht so viele Einschränkungen auferlegt oder so viele Annahmen trifft. Wenn ein C-Programmierer möchte, dass seine Programme portabel sind, muss er sich diese Einschränkungen auferlegen.
In der Praxis ist das wirklich nicht viel schwieriger, als mit den Einschränkungen zu leben, die Java Ihnen auferlegt. Es geht hauptsächlich darum, Ihre Endianness und primitiven Größen zu berücksichtigen und tragbare Bibliotheken wie GTK + anstelle plattformspezifischer Bibliotheken zu verwenden.
Sie könnten ein GTK + -Ziel und einen C-Compiler erstellen, die eine virtuelle Maschine unterstützen, wahrscheinlich sogar die JVM, und vorhandenen Code mit sehr wenigen Änderungen zum Laufen bringen. In der Tat wäre eine virtuelle C-Maschine ohne die Garbage Collection wahrscheinlich viel einfacher. Warum willst du das aber?
Das Umgekehrte, Java in nativen Code zu kompilieren, ist ebenfalls möglich. Genau das macht die JIT. Warum willst du das aber? Ich bin mir sicher, dass es Haustierprojekte gibt, die dies "nur weil" tun, aber sie werden nicht ernsthaft verwendet.
quelle
Du sagtest:
Und da, im ersten Satz, liegen Sie falsch. Java ist aufgrund der JVM nicht portierbar. Java ist portabel, da die Java-Sprache so definiert ist, dass der Implementierer keinen Spielraum für das Verhalten eines Programms hat.
Java hat beispielsweise zwei Typen: "int" (vorzeichenbehaftete 32-Bit-Ganzzahl) und "long" (vorzeichenbehaftete 64-Bit-Ganzzahl). C und C ++ haben "int" (mindestens 16 Bit signiert), "long" (mindestens 32 Bit signiert) und "long long" (mindestens 64 Bit signiert). Das liegt daran, dass C auf vielen verschiedenen Prozessoren ausgeführt werden soll und es ihnen ermöglicht, sich unterschiedlich zu verhalten.
C könnte feste Größen für diese Typen definiert haben. Wenn dies der Fall wäre, hätten 36-Bit-Prozessoren die C-Sprache nicht implementieren können. Und sie können Java tatsächlich nicht implementieren! Daher erlaubte C der Sprache, mit einer Vielzahl verschiedener Computer zu arbeiten. Es ist unvermeidlich, dass dadurch Code erstellt werden kann, der nicht portierbar ist. Es ist eine Frage der Sprache.
quelle
Java ist besonders portabel, da die Sprache auf die Java Virtual Machine abzielt, die, wie der Name schon sagt, keine echte Maschine ist . Da Sie eine virtuelle Maschine auf der Architektur vieler verschiedener Arten realer Maschinen implementieren können, ist ein JVM-basiertes Programm sehr portabel.
C hingegen wurde speziell für die Ausführung mit realer Hardware entwickelt, da es speziell für die Implementierung eines Betriebssystems erstellt wurde, das vollständigen Hardwarezugriff benötigt. Dies bedeutet, dass C-Code vom Design her nicht besonders portabel ist. Wenn Sie ein C-Programm von einer Plattform auf eine andere portieren, müssen verschiedene Teile, die für die Zielarchitektur spezifisch sind, bis zu dem einen oder anderen Grad neu geschrieben werden.
quelle
Es gibt tatsächlich interpretierte Versionen von C , aber sie sind hauptsächlich für schnelle Experimente gedacht und nicht für Produktionssysteme.
Sie sind nicht alltäglich, denn warum würden Sie schließlich alle C-Eigenheiten erleiden, wenn Sie nicht eine kleine, schnelle und statische ausführbare Datei erhalten würden?
quelle
Theoretisch können sowohl C als auch Java zu nativem Code kompiliert, interpretiert oder zu einer virtuellen Maschine kompiliert werden.
Der technische Grund dafür, dass C nicht zu einer virtuellen Maschine kompiliert wird, ist, dass es einfach keine virtuelle Standard- C-Maschine gibt.
Und niemand scheint eine virtuelle C-Maschine definieren oder sogar auf die virtuelle Java-Maschine kompilieren zu wollen (was durchaus möglich ist). Wahrscheinlich, weil niemand, der C benutzt, seine unübertroffene Geschwindigkeit verlieren will. Wahrscheinlich auch, weil C in der Open-Source-Community am stärksten ist, die Portabilität durch Kompilierung (Verteilen und Neukompilieren der Quelle und Ausführen) problemlos durchführen kann, sodass sie die Portabilität der Ausführung (Verteilen und Ausführen einer Binärdatei) nicht als geschlossen empfinden Quellentwickler tun.
quelle
Eigentlich ist das erledigt. Es gibt große Compiler, die die Kompilierung nach LLVM unterstützen (ich weiß, dass Clang dies tut, und ich glaube, dass GCC dies auch tut). Diese LLVM kann JIT-fähig sein, genauso wie Java-Code zu Bytecode kompiliert wird, der JIT-fähig ist.
Was Java jedoch im Vergleich zu C "plattformübergreifend" macht, ist, dass Java über eine große Laufzeitbibliothek verfügt, die auf viele Plattformen portiert wurde. C folgt diesem Paradigma ausdrücklich nicht.
quelle
Es gibt einige wesentliche Unterschiede zwischen Java und C. Java ist über die Java Virtual Machine (JVM) vom Betriebssystem isoliert. Die JVM abstrahiert das Betriebssystem vom Programm. Eine Java-Anwendung fragt möglicherweise die JVM nach einem Speicherblock, und die JVM fragt dann das Betriebssystem nach diesem Speicher. Es gibt viele JVMs für verschiedene Plattformen / Betriebssysteme. Mit der JVM kann dasselbe Java-Programm auf verschiedenen Plattformen ausgeführt werden.
Mit C gibt es keine Betriebssystemisolation. C-Programme werden (normalerweise) direkt auf dem Betriebssystem ausgeführt und führen direkte Betriebssystemaufrufe durch. Dadurch wird das C-Programm an ein bestimmtes Betriebssystem / eine bestimmte Plattform gebunden. Jedes nicht triviale Programm ruft das Betriebssystem auf. Darüber hinaus werden C-Programme in hardwarespezifischen Maschinencode kompiliert. Ein kompiliertes C-Programm für x86 kann nicht direkt auf einem ARM-Prozessor ausgeführt werden.
quelle