Was macht ein Programm (in einer Sprache wie C ++) plattformübergreifend oder nicht?

8

Ich habe ziemlich grundlegende Programmiererfahrung mit Java und habe C ++ und Python ausprobiert. Während es für Java sinnvoll ist, laufen die in C ++ geschriebenen Basisprogramme unter Windows und OS X einwandfrei. Ich konnte die Quelldatei einfach an den anderen Computer senden, kompilieren und ausführen. Die Programme sind ziemlich einfach, meistens nur grundlegende objektorientierte Dinge, die ich getan habe, um C ++ zu lernen.

Natürlich können Sie kein C ++ - Programm auf einem beliebigen Computer kompilieren und es einwandfrei ausführen lassen. Wann passiert das? Ab welcher Komplexität spielt die Plattform eine Rolle und das Programm läuft nicht einfach irgendwo? Ist es, wenn Sie plattformspezifische Bibliotheken verwenden? Könnte ein Programm in C ++ plattformübergreifend erstellt werden, indem nur plattformübergreifende Bibliotheken verwendet werden?

Ich habe versucht, dies selbst herauszufinden, aber alles, was ich gefunden habe, geht mir entweder über den Kopf oder beantwortet einfach nicht die Frage. Vieles, was auftaucht, sind Emulatoren oder Leute, die fragen, welche Sprachen plattformübergreifend sind.

Chris
quelle
2
Plattformspezifische Bibliotheken, nicht standardmäßige Compilererweiterungen, jegliche Abhängigkeit davon, wie Bits tatsächlich im Speicher angeordnet sind, und jede andere Form von undefiniertem / nicht spezifiziertem Verhalten sind die typischen Gründe, die ich kenne, damit Code plattformspezifisch wird. Wenn Sie all dies vermeiden, ist C ++ standardmäßig ziemlich portabel.
Ixrec
"Könnte ein Programm in C ++ plattformübergreifend erstellt werden, indem nur plattformübergreifende Bibliotheken verwendet werden?" Dies ist meistens wahr. Sie müssen auch für jede Plattform kompilieren (die Binärdateien erstellen), da der kompilierte Maschinencode für die Architektur spezifisch ist.
Rwong
1
Sie können Qt- oder POCO- Frameworks verwenden.
Basile Starynkevitch

Antworten:

6

Es gibt eine sehr klare Linie im Sand zwischen Querplattform und Monoplattform:

Verwendet ein Programm nur die APIs, die in der Standardbibliothek verfügbar sind, auf der es basiert?

Wenn Sie auf eine Standardimplementierung abzielen, sollte jede Plattform, die diesen Standard implementiert, Ihr Programm theoretisch korrekt kompilieren und ausführen. Es gibt viele Ausnahmen, aber im Allgemeinen sollten Sie viele dieser Ausnahmen vermeiden können, wenn Sie clevere Tricks vermeiden.

Der Grund, warum dieses Problem speziell bei C ++ auftritt, ist, dass die C ++ - Standardbibliothek lange Zeit nicht viele Module enthielt, die für nicht triviale Programme nützlich sind. Parallelität und GUI sind die beiden großen. Dies bedeutete, dass ein Programm, das nur mit der C ++ - Standardbibliothek erstellt wurde, nicht viele der Funktionen aufweisen konnte, die wir von moderner Software erwarten.

Wie schreiben wir plattformübergreifende Software, die Dinge tut, die die Standardbibliothek nicht unterstützt?

Sie erwähnen "plattformübergreifende Bibliotheken", die in der Praxis je nach Umfang normalerweise als "Frameworks" oder "Toolkits" bezeichnet werden. Die Möglichkeit, plattformübergreifende Software in C ++ zu schreiben, besteht darin, nicht nur auf die Standardbibliothek abzuzielen, sondern auch auf ein Framework, das auf Ihren Zielplattformen aufbaut.

Im Wesentlichen werden die plattformspezifischen Bits an eine andere Bibliothek ausgelagert. Zum Beispiel ist wxWidgets ein beliebtes Framework. Sie können seine Klassen verwenden, um eine GUI und zugehörige Funktionen zu erstellen (z. B. Standarddialoge zum Auswählen von Dateien). Unter dem Deckmantel wird die bedingte Kompilierung verwendet, um die GUI unter Verwendung der nativen GUI für jede Plattform zu implementieren. Aber als Benutzer der Bibliothek ist Ihnen nichts davon wichtig.


Historischer Hinweis: Hier im Jahr 2015 sind C ++ - Compiler und -Bibliotheken größtenteils wirklich gut. Gehen Sie ein paar Jahre zurück, und das ist nicht wahr. C ++ hatte erst 1998, viele Jahre nach seiner Einführung, einen offiziellen Standard. Es dauerte lange, bis die Anbieter ihre Compiler und Bibliotheken aktualisiert hatten, um den Standard korrekt zu implementieren. Herstellerspezifische Erweiterungen gibt es zuhauf (und gibt es eigentlich immer noch). Einige Compiler hatten nicht standardmäßige Header und Funktionen. Code-Portabilität war praktisch nicht vorhanden. Der Ruf von C ++ in Bezug auf Portabilität leidet immer noch.


quelle
5

Ab welcher Komplexität spielt die Plattform eine Rolle und das Programm läuft nicht einfach irgendwo?

Grundsätzlich alles nicht triviale. Wenn Sie ein nicht-triviales Programm schreiben, Sie werden bis versehentlich auf eine Compiler-spezifische Art und Weise abhängig beenden , dass es Aufträge Überlastungen, Blicke auf Namen und anderen komplexe Dinge. Darüber hinaus hängen praktisch alle nicht trivialen Programme von einem nicht standardmäßigen plattformspezifischen Verhalten ab, da der Standard nur wenige Container bereitstellt.

Nicht triviale Programme können sich jedoch stark darin unterscheiden, wie einfach sie auf eine andere Plattform portiert werden können. Wenn Sie es gut programmiert haben und sich an die Regeln halten, können Sie ziemlich einfach portieren und einen Bonus erhalten, wenn Sie die Teile in eine Bibliothek abstrahieren können (die möglicherweise bereits für Sie bereitgestellt wurde, z. B. Boost.Filesystem).

Programme lassen sich meist nur sehr schwer zwischen Plattformen portieren, wenn sie Aufgaben ausführen, die von Natur aus plattformspezifisch sind, z. B. das Schreiben von Daten auf die Festplatte mit bestimmten Atomizitäts- / Konsistenzgarantien, oder wenn Sie ein Idiot waren und dumme Dinge taten Niemals das, was Sie eigentlich hätten tun sollen, wie zwischen Ints und Zeigern zu gießen.

DeadMG
quelle
2
Sicherlich übertreibt dies den Fall? Ich weiß, dass mehr esoterischer C ++ - Code in älteren oder minderwertigen Compilern auf verschiedene Compilerfehler stoßen kann, aber jeder vernünftig standardkonforme Compiler sollte Dinge wie Überladung und Namenssuche gleich behandeln. Die Standardbibliothek bietet E / A und (beginnend mit C ++ 11) Threading, und die Unterstützung von Dateisystemen wird standardisiert.
Josh Kelley
@JoshKelley: Das ist im Grunde nichts im Vergleich zu dem, was die meisten Programme erfordern. Außerdem implementieren einige sehr verbreitete Compiler wie MSVC Überladung, SFINAE und Namenssuche unterschiedlich mit unterschiedlichen beobachtbaren Ergebnissen.
DeadMG
1

In sehr einfachen Worten, was ein Programm plattformübergreifend macht, ist Ihre Fähigkeit, die Quellen aus einer Umgebung zu entnehmen, sie in einer anderen zu kompilieren und das fertige Produkt wie erwartet arbeiten zu lassen.

In weniger einfachen Worten gibt es eine vollständige Überschneidung zwischen dem, was das Programm erwartet, und dem, was Ihre Zielumgebungen bieten. Sobald Sie etwas getan haben, bei dem die Überlappung weniger als 100% beträgt, z. B. die Verwendung einer umgebungsspezifischen Bibliothek oder eines Sprachfeatures mit undefiniertem Verhalten, haben Sie Ihr Programm an die Umgebungen gebunden, die die nicht überlappenden Features bereitstellen können.

("Plattform" ist ein ziemlich matschiges Wort. Die Leute können über Windows und Unix als Plattformen oder Linux, OS X, BSD und Solaris als Plattformen sprechen, obwohl sie alle nominell Unix sind Hardware-Architekturen und Dinge werden noch nebulöser. Nachdem ich das gesagt habe, werde ich anfangen, das Wort zu verwenden.)

Glücklicherweise gibt es Standards, um dieses Problem zu lösen:

Sprachen. Sie schreiben C ++, das 1998 erstmals von der ISO standardisiert wurde. Jedes Programm, das Sie schreiben und das diesem Standard entspricht, kann mit den erwarteten Ergebnissen auf jeder Plattform mit einem konformen Compiler und einer entsprechenden Laufzeit kompiliert und ausgeführt werden. Der Größe oder Komplexität des Programms sind keine Grenzen gesetzt, solange es nicht vom Standard abweicht. Wenn ein Programm, das nachweislich den Standard erfüllt, auf einer bestimmten Plattform nicht wie erwartet ausgeführt wird, wird die Implementierung der Sprache auf dieser Plattform verdächtig. Viele Sprachen verfügen über sorgfältig gestaltete Testsuiten, mit denen die Konformität überprüft werden kann.

Java wird besonders erwähnt, weil es nicht nur eine Sprache standardisiert, sondern auch Objektcode standardisiert, wodurch seine Programme überall ohne Neukompilierung ausgeführt werden können. Dies wird erreicht, indem der Konformitätspunkt um eine zusätzliche Ebene in eine plattformangepasste virtuelle Maschine (oder sogar Hardware) verschoben wird, auf der der Objektcode ausgeführt werden kann.

APIs. Die Aufrufe, die Sie tätigen, damit Ihr Programm bestimmte Dinge ausführt, können ebenfalls standardisiert werden. Wie Sprachen können diese APIs und die Bibliotheken, die sie implementieren, so eingerichtet werden, dass sie sich so verhalten, wie es die Aufrufer erwarten, indem sie eine zugrunde liegende Implementierung verwenden, die für eine bestimmte Plattform geeignet ist. Eine solche API sind die POSIX- Standards des IEEE , die entwickelt wurden, um die Fragmentierung einzudämmen, die in den 1980er Jahren unter Unix stattfand. (Ich war damals in der Nähe; dieser Aspekt hat keinen Spaß gemacht.) Durch die Definition von Standardaufrufen und -verhalten konnten Systemanbieter ihren Kunden das Vertrauen geben, dass die Migration auf ihr Betriebssystem nicht so viel Arbeit bedeuten würde wie in der Vergangenheit. POSIX wurde weit verbreitet eingesetzt und ist fast 30 Jahre später immer noch weit verbreitet.

Ich habe zahlreiche Projekte durchgeführt, die sich sklavisch an die Standards hielten, weil ich wusste, dass sie auf mehreren Plattformen ausgeführt werden mussten. Was ich für meine Probleme bekam, war Code, der überall funktionierte, wo ich ihn ausführen wollte, und mich bei einigen angenehm überraschte, bei denen ich es nicht getan hatte.

Blrfl
quelle
0

Grundsätzlich, wenn Sie Dinge außerhalb Ihres Programms "berühren". Ein besonderer Fall (ich wage nicht zu sagen, der einzige Fall) ist, wenn Sie Bibliotheken verwenden, die sich auf das Betriebssystem beziehen. Dinge wie die Verwendung des gemeinsamen Speichers zwischen Prozess und Drucken ausgefallener Dinge auf der Konsole. Im ersten Fall greifen Sie auf einen Speicher zu, der vom Betriebssystem verwaltet wird, im zweiten Fall wird der Bildschirm auch vom Betriebssystem gesteuert.

Das Ausführen einer GUI hängt vom Betriebssystem ab, aber es gibt GUI-Bibliotheken, die plattformübergreifend sind, sodass Sie sich darüber keine Sorgen machen müssen. Zumindest theoretisch.

Es ist schwierig, etwas Nicht-Triviales plattformübergreifend zu machen. Das Gute daran ist, dass es nicht so schwierig ist, Software portabel zu machen, wenn Sie die richtigen Bibliotheken verwenden und ordnungsgemäße Tests durchführen, zumindest wenn der Code nicht zu groß ist. Wie groß zu groß ist, hängt von der Größe Ihres Teams, der Programmierkenntnis usw. ab.

cauchy
quelle