28.10.2014

Programmiersprachen ohne "Objektcode": Konsequenzen für die Vertragsauslegung

Portrait von Oliver Stiemerling
Oliver Stiemerling Öffentlich bestellter und vereidigter Sachverständiger für Systeme und Anwendungen der Informationsverarbeitung

In vielen Verträgen und Lizenzen findet sich der technische Begriff „Objektcode“ im Sinne von aus Quellcode übersetztem, ausführbarem Code. Das kann nicht nur für Programmierer sondern auch für die Auslegung des Vertrags durchaus verwirrend sein, denn Objektcode ist etwas, das es in vielen modernen Programmiersprachen in dieser Form heute nicht mehr gibt. Und direkt ausführbar ist Objektcode meistens auch nicht.

Was ist Objektcode?

Objektcode ist genau genommen nur ein Zwischenprodukt bei einer speziellen Art von Compilern, die zunächst die einzelnen Module aus dem Quellcode in grundsätzlich maschinenausführbaren Code (Maschinencode bzw. Binärcode) übersetzen.

Der maschinenausführbare Code ist allerdings noch nicht mit anderen übersetzten Modulen statisch zu einem ausführbaren Programm verbunden („gelinkt“). Beim Linken werden dann insbesondere die Aufrufadressen der einzelnen Funktionen in den Modulen gemäß der Position des jeweiligen Moduls im Gesamtprogramm angepasst, so dass die Module sich im Gesamtprogramm korrekt gegenseitig aufrufen können. Dann erst ist das Ergebnis funktionsfähig (z.B. als ausführbares EXE-File für ein Windows-Betriebssystem).

Im Filesystem des Entwicklungsrechners finden sich bei Objektcode nutzenden Sprachen wie C++ beispielsweise Dateien mit der Endung:

  • "*.c" als Sourcecode,
  • "*.obj"-Dateien als Objektcode und
  • abschließend eine "*.exe"-Datei als ausführbares Programm.

Objektcode ist ein wichtiges Konzept, da man damit bei größeren Programmen ein wiederholtes Übersetzen von unverändertem Code vermeiden kann. Es wird nur das geänderte Modul neu in Objektcode übersetzt und dann beim Linken mit den anderen, unveränderten Objektdateien verbunden. Das spart teure Rechenzeit. Allerdings ist Rechenleistung heute nicht mehr so teuer wie vor vierzig Jahren, so dass diese Motivation für Objektcode naturgemäß in den Hintergrund tritt.

Zusätzlich kann man mit Hilfe des Objektcodekonzepts aber auch eine Anwendung so ausliefern, dass man dem Kunden nur Teile eines ausführbaren, statisch gelinkten Programms im Sourcecode zur Verfügung stellen muss. So kann der Hersteller einem Kunden erlauben, bestimmte Teile eines Gesamtprogramms zu verändern, während der Quellcode anderer Teile geheim und unveränderbar bleibt.

Java als Beispiel für eine Programmiersprache ohne "Objektcode"

Aus der Sicht des Entwicklers erzeugt ein Java-Compiler überhaupt keinen Objektcode. Wenn man eine Datei mit der Endung "*.java" durch den Compiler übersetzen lässt, so wird direkt eine "*.class"-Datei erzeugt. Diese Datei enthält sogenannten Bytecode, der im Gegensatz zu Objektcode-Dateien keinen echten Maschinencode (Binärcode) für einen physischen Prozessor enthält, sondern lediglich für eine virtuelle Maschine. Auch muss dieser Code nicht statisch mit dem Rest eines Java-Programms „verlinkt“ werden. Es reicht, die "*.class"-Datei in den sogenannten „classpath“ der jeweiligen virtuellen Maschine zu legen, so dass sie bei der Ausführung automatisch gefunden und dynamisch mit dem ausgeführten Programm verbunden wird.

  • Vorteile:

Diese Vorgehensweise hat den Vorteil, dass ein Java-Bytecode-Programm auf jedem Rechner ausführbar ist, für den es eine virtuelle Maschine gibt. Zudem ist Java-Bytecode – solange es von einer kompatiblen Java-Compiler-Version stammt – auch einfach einzeln als "*.class"-File austauschbar. Man kann also einem nur im Java-Bytecode vorliegenden Programm ein einzelnes, ggf. verbessertes "*.class"-File „unterschieben“, ohne dass man das gesamte Programm neu „linken“ oder sogar kompilieren müsste.

  • Funktionsweise:

Wirklich auf einer physischen CPU ausführbarer Maschinencode wird erst innerhalb der virtuellen Maschine erzeugt. Die meisten modernen virtuellen Maschinen arbeiten so, dass der Bytecode vorausschauend kurz vor der Ausführung in sehr schnell laufenden Maschinencode (echten Binärcode) übersetzt (sog. "Just-in-time Kompilierung"). Einfachere virtuelle Maschinen interpretieren den Bytecode ohne vorherige Übersetzung, d.h. sie führen für jeden Bytecode-Befehl vorgegebene Binärcode-Fragmente aus. Diese Vorgehensweise ist typischerweise langsamer als das vorausschauende Übersetzen.

  • Ziel:  Maschinenunabhängigkeit

Die Konzepte von Java werden auch in anderen modernen Sprachen wie C# (sprich C-Sharp) verwendet, da insbesondere die Vorteile der Maschinenunabhängigkeit in der heutigen Welt mit unterschiedlichsten mobilen und stationären Rechenplattformen (vom Mobiltelefon bis hin zur Set Top-Box auf dem Fernseher) so viele verschiedene, inkompatible Prozessoren verwendet werden, dass ein effiziente Anwendungsentwicklung für multiple Plattformen unmöglich ist.

Fazit

Wenn heute in einer Lizenz, einem IT-Vertrag oder auch in einer Hinterlegungsvereinbarung immer noch aus „historischen" Gründen von „Objektcode“ die Rede ist, besteht die reale Gefahr, dass es diese Code-Art in der betroffenen Programmiersprache gar nicht gibt und dann im Streitfall erst „mühsam“ der von den Parteien gewünschte Sinn des geschlossenen Vertrages erarbeitet und interpretiert werden muss.

Idealerweise benennt man die Software-Artefakte in juristischen Dokumenten mit den tatsächlich verwendeten Begriffen. Alternativ könnte man auch etwas abstrakter die Rolle der gewünschten Dateien im Übersetzungsprozess beschreiben, wenn man Technologie-unabhängig bleiben will. Ein Beispiel für diese Vorgehensweise ist der Begriff „geeigneter Shared-Library-Mechanismus“ aus der LGPL.

 

Zurück