(Un)endlich portabel

Vier Jahre brauchte es, bis sich die Unix-Entwickler den Wunsch nach einer komfortablen Entwicklungsumgebung selbst erfüllten. Seither sind 40 Jahre vergangen, in denen C und mit ihm die plattformübergreifende Portabilität von Betriebssystemen und Anwendungen zum Programmieralltag gehören.

In Pocket speichern vorlesen Druckansicht 6 Kommentare lesen
Lesezeit: 11 Min.
Von
  • Susanne Nolte
Inhaltsverzeichnis

Bei wenigen Programmiersprachen herrscht so viel Unklarheit über das genaue Geburtsdatum wie bei C. Nur eines ist klar: Anfang 1973 war C im Kern fertig. Überliefert hat dieses Datum der inzwischen verstorbene Dennis Ritchie: „By early 1973, the essentials of modern C were complete.“ [1] Nun, so Ritchie weiter, waren Sprache und Compiler stabil genug dafür, den Unix-Kernel für die PDP-11 neu zu schreiben.

Doch von vorn: Wie die Geschichte von Unix beginnt auch die von C mit dem Multics-Projekt (Multiplexed Information and Computing Service), mit dem das MIT (Massachusetts Institute of Technology), General Electric und die Bell Labs ein Multi-User- und Multi-Tasking-System schaffen wollen [2]. 1969 jedoch kommen Management und Entwickler der Bell Labs zu der Überzeugung, dass das Multics-Projekt dieses Ziel nur mit zu viel Aufwand und zu spät erreichen wird – zu umfangreich und ressourcenfressend ist die bisherige Multics-Version bereits.

Nachdem sich das Bell-Labs-Team aus dem Projekt zurückgezogen hat, sucht eine kleine informelle Gruppe um Ken Thompson nach Alternativen. Zu ihr gehören Dennis Ritchie, Doug McIlroy und Joseph Ossanna [3]. Thompson will eine komfortable Anwendungsumgebung nach eigenen Vorstellungen schaffen und ist von vielen Ideen des Multics-Projekts angetan: Ein baumartiges Dateisystem, eine Prozessverwaltung als Steuerungszentrale, ein Kommando-Interpreter als User-Level-Programm, eine einfache Darstellung von Textdateien und ein allgemeiner Zugriff auf die Peripherie zählen zu den Innovationen von Multics.

Für das eigene Projekt steht jedoch nur eine nicht mehr ganz aktuelle DEC PDP-7 ohne geeignete Entwicklungsumgebung zur Verfügung. Dass Multics in einer Hochsprache geschrieben ist, empfinden Thompson und Co. als Vorteil, da Hochsprachen im Vergleich zu Assembler verständlicher sind und einfacher zu schreiben. Allerdings findet die Multics-Implementierungssprache PL/I selbst keinen großen Anklang im Team.

Andere Hochsprachen hingegen erfreuen sich im Team durchaus einer gewissen Beliebtheit, etwa BCPL (Basic Combined Programming Language). Mit der BCPL, die Martin Richards Mitte der 1960er während seiner Zeit am MIT entwickelte, kam das Bell-Labs-Team zuvor während seines Multics-Engagements in Kontakt: Das CTSS-System (Compatible Time-Sharing System) des MIT, auf dem sich die BCPL-Umgebung befand, war in die Multics-Entwicklung eingebunden. Den dortigen Original-Compiler hatten Rudd Canaday und andere Kollegen der Bell Labs auf Multics und auf das GE-635-Betriebssystem GECOS portiert. Diese typenlose Sprache erweist sich aber als ungeeignet für das Vorhaben.

Den Plan, ein System-Fortran, also eine für Betriebssysteme geeignete Fortran-Version zu schreiben, verwirft Thompson schnell. Auch mit ALGOL 68 liebäugelt das Team vorübergehend. Denn: Fortran, PL/I und Algol 68 sind zwar in dieser Zeit weit verbreitet, das Anpassen und Entwickeln geeigneter Compiler erfordern jedoch Ressourcen, die das kleine Team nicht besitzt. Kleinere und einfachere Werkzeuge müssen also her. Dennis Ritchie: „All these languages influenced our work, but it was more fun to do things on our own.“ [1]

Aufgrund der Ressourcenknappheit muss das Team die Frage nach einer komfortablen Entwicklungsumgebung sowieso vertagen. Zudem kommt der Portierbarkeit des neuen Betriebssystems, für das Peter Neumann 1970 den Namen Unics (UNiplexed Information and Computing Service) findet, zu diesem Zeitpunkt noch keine große Bedeutung zu.

Herhalten muss deshalb ein Assembler, allerdings nicht auf der PDP-7, sondern ein GEMAP-Assembler auf einer GE-635. Ein Postprozessor generiert den für die PDP-7 lesbaren Code, den die Entwickler auf Lochstreifen stanzen und zur PDP-7 tragen. Diesen Transportweg geht der Code so lange, bis ein primitiver Unix-Kernel, ein Dateisystem, eine Shell, ein Editor, ein Assembler und erste Unix-Werkzeuge wie rm, cat und cp ihr neues Heim bezogen haben. Mit ihnen haben Thompson und seine Leute die Umgebung geschaffen, die sie für die Weiterentwicklung auf der PDP-7 benötigen.

Thompsons PDP-7-Assembler ist eine vereinfachte Version des DEC-Assemblers für die PDP-7, ohne Libraries, Loader oder Link-Editor. Er bekommt den gesamten Source-Code in einer Datei übergeben und gibt eine Binär-Datei mit dem Namen a.out (Assembler Output) aus. Denselben Namen trägt das von Thompson gewählte Dateiformat, das zwar inzwischen von den Nachfolgern Executable and Linking Format (ELF) und Common Object File Format (COFF) abgelöst wurde, aber immer noch unterstützt wird. Noch heute ist es der Standard-Ausgabe-Name vieler Compiler und Assembler unter Unix-Derivaten, ganz gleich, ob sie a.out-, ELF- oder COFF-Binaries produzieren.

Noch im Jahr 1969 schreibt Doug McIlroy den ersten Hochsprachen-Compiler für das junge Unix. Die Wahl fällt auf die von Robert M. McClure entworfene Compiler-Compiler-Sprache TMG (TransMoGrifier). McIlroy und Robert Morris, dessen Sohn Robert Tappan Morris knapp 20 Jahre später versehentlich den nach ihm benannten Unix-Wurm freisetzt, schrieben bereits in den 1960ern den ersten PL/I-Compiler für Multics in TMG.

Kaum ist der TMG-Compiler auf der PDP-7 fertiggestellt, beschließt Thompson, dass das neue Betriebssystem eine eigene Programmiersprache braucht. Ein kurzes Fortran-Intermezzo bringt ihn zu BCPL zurück. Auf deren Grundlage entwickelt Thompson 1969 die Sprache B. Da die PDP-7 nur 8 KByte RAM besitzt, muss Thompson auf einige BCPL-Fähigkeiten verzichten, etwa auf verschachtelte Funktionsdefinitionen. Zudem erzeugt der Compiler lediglich einen Zwischencode oder Threaded Code, der zur Laufzeit einen Interpreter benötigt [1], was ebenfalls den Arbeitsspeicherbedarf klein hält.

Als die in TMG geschriebene Version des B-Compilers und Interpreters stabil läuft, schreibt Thompson eine zweite Version in B. Im Laufe der Arbeiten fügt er die Operatoren „++“ und „- -“ hinzu, noch auf der PDP-7. Derweil setzt sich Dennis Ritchie daran, einen Cross-Compiler zu schreiben, der B-Code in maschinenlesbare GE-635-Instruktionen übersetzt – aufgrund der größeren Ressourcen ohne Umweg über einen Interpreter.

1970 kann Unix auf eine neu erworbene und wesentlich aktuellere PDP-11 umziehen. Der Umzug bringt zwei Neucodierungen mit sich: die von Unix und die des B-Compilers. Nun wird deutlich: Durch ihren Laufzeit-Interpreter ist B für die Betriebssystem-Entwicklung nicht performant genug.

Zudem verlangt die wortorientierte Sprache auf der Byte-orientierten PDP-11 weitere Klimmzüge. Darüber hinaus steht die Unterstützung von Floating-Point-Berechnungen vor der Tür; dies zumindest verspricht DEC. Die voluminösen BCPL-Compiler auf den Multics- und GECOS-Systemen beherrschten bereits Floating-Point-Berechnungen durch die Definition spezieller Operatoren. Dieser Weg ist jedoch auf der 16-Bit-Maschine, auf der eine Gleitkommazahl mehr als ein Wort benötigt, nicht gangbar. Außerdem implizieren die Modelle von BCPL und B einen Overhead beim Umgang mit Pointern.

Das alles bewegt Dennis Ritchie 1971 dazu, die Sprache mit Datentypen auszustatten. Dies wiederum verlangt weitere Änderungen der Syntax. Zudem muss ein neuer Compiler her. Aufgrund dieser Strukturänderung benennt Ritchie die Sprache zunächst in NB (New B) um, entscheidet sich aber kurze Zeit später, bei einem Buchstaben zu bleiben. Dabei lässt er offen, ob er der Reihenfolge im Alphabet oder in der Zeichenfolge BCPL gefolgt ist. Brian Kernighan, der später AWK (Aho, Weinberger, Kernighan) und AMPL (A Mathematical Programming Language) mitentwickelt, steuert die Dokumentation zur neuen Sprache bei [5].

Erst danach – 1972 – kann die Portierung von Unix auf die Hochsprache beginnen. Doch scheitert der erste Anlauf an weiteren Unzulänglichkeiten der jungen Sprache. Als die Anfang 1973 behoben sind, können die Entwickler die Portierung von Unix in C im Sommer 1973 abschließen: Unix V4 kann als weitgehend plattformunabhängiges System seinen Streifzug durch die Welt der Hardwareplattformen antreten. Kurz nach dem ersten Unix-Vortrag auf dem vierten ACM Symposium on Operating Systems Principles (Association for Computing Machinery) im Oktober 1973 [6] erhält die UCB (University of California, Berkeley) eine Kopie von Unix V4 samt Compiler und beginnt umgehend mit Erweiterungen.

Nach mehreren Manual-Versionen veröffentlichen Brian Kernighan und Dennis Ritchie 1978 die erste Auflage von The C Programming Language. Die darin beschriebene C-Version beinhaltet bereits Erweiterungen wie zusätzliche Datentypen und die I/O-Standardbibliothek stdio. Diese nach den Buchautoren „K&R C“ genannte Spezifikation gilt lange als informelle C-Referenz.

Da sich C weiter rasant verbreitet und in den unterschiedlichen C-Compilern zu zerfasern droht, nimmt 1983 das ANSI-Komitee X3J11 seine Arbeit auf. 1989 verabschiedet das American National Standards Institute die Norm ANSI X3.159-1989 Programming Language C (C89). Im Jahr darauf übernimmt die ISO die Norm mit kleinen Änderungen als C90. 1995 folgt die Ergänzung C95.

Ein eigener Standard ISO/IEC 9899 folgt 1999. In die C99 genannte Version fließen erstmals C++-Erweiterungen zurück. Die nächste C-Erweiterung unter dem Arbeitstitel C1X veröffentlicht die ISO am 8. Dezember 2011 als C11.

Es ist also noch kein Ende in Sicht. Zugleich beeinflusste C auch viele andere Programmiersprachen direkt und indirekt. Zu Ersteren zählen Objective-C, C++, PHP, D, C#, F#, Vala und das erst 2009 von Google vorgestellte Go – Co-Autor: Ken Thompson.

[1] Dennis M. Ritchie; The Development of the C Language; in: Thomas J. Bergin; Richard G. Gibson; History of Programming Languages II; ACM Press/Addison-Wesley 1996; und cm.bell-labs.com/cm/cs/who/dmr/chist.html

[2] Susanne Nolte; Jubiläum; Schwaches Wortspiel; Viele Aufgaben, viele Benutzer: Unix wird 40 Jahre alt; iX 08/2009, S. 96

[3] Dennis Ritchie; The Evolution of the Unix Time-sharing System; cm.bell-labs.com/cm/cs/who/dmr/hist.html

[4] Ken Thompson; Users’ Reference to B; Bell Labs Technical Memorandum; January 7, 1972; cm.bell-labs.com/cm/cs/who/dmr/kbman.html

[5] Brian. W. Kernighan, Dennis M. Ritchie; The C Programming Language; 1978, Second edition, 1988

[6] Dennis M. Ritchie, Ken Thompson; The UNIX Time-Sharing System; Communications of the ACM; July 1974, Volume 17, Number 7 und cm.bell-labs.com/who/dmr/cacm.html

Alle Links: www.ix.de/ix1302124 (sun)