C++ die schlimmste Programmiersprache ever


Schaut man sich den Sourcecode von C++ einmal an, so kommt einem da das Grausen. An der Sprache selbst liegt es jedenfalls nicht. Sowohl der Programmierstil von C ist sehr elegant und auch das Konzept der Objektorientierung gehört zum Goldstandard um komplexe Programme zu schreiben. Ich glaube, C++ ist deshalb keine gute Wahl weil dort beides miteinander verbunden wurde. Doch fangen wir schön der Reihe nach an, und zwar mit C. C ist eine sehr schöne Sprache, es gibt dafür leistungsfähige Compiler und man kann damit sehr mächtige Dinge tun. Vor allem ist es die ideale Sprache wenn man Betriebssysteme und Compiler schreiben möchte. Auch die Nutzung von Pointern, Structs usw. sind wichtige Elemente. Die fehlende Objektorientierung kann man verschmerzen, man kann sich auch so helfen.

Schauen wir uns noch eine weitere Sprache an: Python. Auch das ist eine sehr schöne Sprache. Sie ist ausgezeichnet für Quick&Dirty Prototypen geeignet und man kann daran ausgezeichnet GUI Applikationen erstellen. Der Code von Python ließt sich übersichtlich und es gibt ausgezeichnete Tutorials dazu. Jetzt liegt natürlich die Idee auf der Hand die eine Supersprache zu schaffen, die einerseits objektorientiert ist aber auf der anderen Seite so mächtig ist wie C. Komischerweise gibt es diese ideale Sprache namens C++ bereits. Leider ist das Ergebnis nicht überzeugend. C++ wirkt auf C Programmierer vollkommen überdimensioniert, weil sie die ganzen objektorientierten Features nicht benötigen. Auf Python Programmierer hingegen wirkt C++ zu systemnah, weil man dort nicht auf die schnelle Code hinschreiben kann, sondern ihn zuvor immer kompilieren muss. Anders formuliert, C++ ist eine Sprache mit der sich weder High-Level-Anwendungen noch lowlevel Machinencode richtig erstellen lassen.

Schauen wir uns jetzt die sogenannten Nachfolger von C++ genauer an: hier ist Java und C# zu nennen. Beide sind mit dem Versprechen angetreten, dass bessere C++ zu realisieren. Wo also auch Einsteiger gut mit klarkommen. Leider wurde dort der Fehler von C++ wiederholt. Auch Java ist auf der einen Seite konsequenz auf das objektorientierte Paradigma hin fokussiert will aber gleichzeitig eine Universalsprache sein. Einerseits sollte sich damit leicht Programme schreiben lassen, auf der anderen Seite will es mächtig und hochperformant sein. Wiederum funktioniert das nicht gut.

Ich glaube der Fehler den C++ und ähnliche Sprache machen ist einen Spagat zu wagen zwischen zwei Programmierparagidmen: kompilierte Sprache und objektorientierte Sprachen. Meine Hypothese lautet, dass man zwei unterschiedliche Programmiersprachen benötigt:

1. Systemnah, kompiliert, strukturiert
2. Anwendungsnah, scripting, objektorientiert

Der Versuch die Eigenschaften zu mischen muss scheitern. Man kann nicht eine Sprache schaffen, die sowohl kompiliert als auch gescriptet wird, und man kann keine Sprache haben, die sowohl objektorientiert als auch strukturiert funktioniert. Schauen wir uns nochmal das eingangs erwähnte C näher an. Es ist eine rein strukturierte Sprache wo es keinerlei objektorientierte Features gibt. Könnte man C dadurch verbessern, indem man Klassen einbaut? Natürlich nicht, damit würde man C zerstören. C with Classes funktioniert nicht. Das Konzept der Klassen benötigt man nur, wenn man sehr große Programme schreiben möchte, wie z.B. Spiele. Wenn man hingegen Bibliotheken schreiben will, braucht man keine Klassen sondern man braucht effiziente Algorithmen die gut getestet wurden.

ich wage mal die These, dass man objektorientierte Programmierung immer in Verbindung mit einer Scripting Sprache betrachten sollte. Wo also die Programmerstellung interaktiv erfolgt und wo das Schreiben von Prototypen im Vordergrund steht. Python oder Smalltalk sind dafür gute Beispiele: man schreibt eine Klasse, testet sie und verbessert sie zur Laufzeit. Und als Klassen werden auch Grafikelemente wie Rechteck definiert.

Manchmal wird gesagt, dass der G++ Compiler den älteren GCC Compiler abgelöst hätte. Doch das ist nicht wahr. Gerade Leute die wirklich Programmcode schreiben nutzen GCC und zwar aus ideologischen Gründen. Zwar kann man C-Code auch mit C++ Compiler übersetzen, aber das ist nicht das selbe. Objektorientierte Features haben auf Systemebene nichts verloren. Der Tag wo Linus Torvalds anfängt in seinen Linux-Kernel Klassen einzubauen wäre es Zeit sich nach einer Alternative umzusehen.

Ich bin keineswegs gegen objektorientierte Programmierung oder gegen eine virtuelle Maschine eingestellt. Ganz im Gegenteil, es sind moderne wie auch leistungsfähige Features die die Programmierung vereinfacht haben. Was jedoch nicht geht ist, lowlevel Sprachen mit High-Level-Sprachen zu mischen. Man kann das bei C++ sehen, aber Java macht den selben Fehler. Ich will mal konkret sagen, was der Designfehler von C++ ist. Der Fehler ist, dass man dort das Schlüsselwort class eingefügt hat. Klassen kann man in Lua oder PHP nutzen, aber nicht auf Systemebene.

Von der Ablaufgeschwindigkeit ist C ungefähr gleichauf mit Java. Das heißt, selbst wenn bei GCC den -O3 Schalter aktiviert kann man es nicht schaffen schneller zu sein als Java. Aber, Java ist dennoch nicht in der Lage C zu ersetzen, bis heute ist es nicht gelungen ein Java Betriebssystem für Desktop Computer zu entwickeln und es wird vermutlich niemals passieren. Selbst in 30 Jahren dürfte C noch Verwendung finden was bei Java und C++ nicht so sicher ist. Das hat nicht unbedingt mit der Sprache als solche zu tun, sondern vielmehr geht es um das Drumherum. Also wie ein C-Tutorial aufgebaut ist.

Um C näher zu bewerten lohnt sich ein Blick auf das ominöse objektorientierte Programmieren. Es handelt sich dabei eigentlich um sehr schlechten Programmierstil. Man programmiert objektorientiert wenn man globale Variablen einführt und diese in einem Struct kapselt. Beides Dinge die man als C Programmierer vermeiden sollte. Dennoch hat sich OOP durchgesetzt, weil man damit sehr eleganten Code schreiben kann. Aber heißt das, dass OOP besser ist als strukturierte Programmierung? Nein, sondern es ist für andere Aufgaben nur besser geeignet. OOP kommt immer dann zum Einsatz wenn bereits Bibliotheken da sind, wenn man also schon ein Betriebssystem hat, das Fenster unterstützt und womöglich sogar schon eine Game-Engine programmiert wurde, und man jetzt nur noch in 100 Lines of Code ein Pong Spiel schreiben will. Für was ist OOP ideal.

Ich glaube der Grundfehler von C++ war, dass es das objektorientierte Feature in eine kompilierte Sprache hineingelegt hat. Das beißt sich. Mit kompilierten Sprachen arbeitet man nur, wenn man lowlevel Bibliotheken schreibt die auf Systemebene agieren, was hat auf dieser Ebene OOP verloren? Richtig gar nichts. Wie eingangs erwähnt handelt es sich um extrem schlechten Programmierstil der globale Variablen nutzt. Sowas gilt es möglichst zu vermeiden, besonders dann wenn der Code schlank und effizient sein soll.

Historisch gesehen wurde C++ entwickelt als das bessere Smalltalk. Smalltalk war eine OOP Sprache, die jedoch sehr langsam war. Also kam Bjarne Stroustrup auf die Idee doch einfach den Code vor Ausführung zu kompilieren. Das wird als die Geburtsstunde von C++ bezeichnet. Laut der Selbstdarstellung wurde damit eine Sprache geschaffen die so schnell war wie C, aber so mächtig wie Smalltalk. Aber ist C++ wirklich schnell? Die hohe Performance wurde erkauft durch die Nutzung eines Compilers. Wenn man C++ Code verändert muss man anders als bei Smalltalk einen Compile-Zyklus einbauen. Konnte man bei Smalltalk sogar zur Laufzeit den Code verändern geht das bei C++ nicht mehr. Auf der anderen Seite fühlten sich C Programmierer von C++ abgestoßen, weil sie mit OOP Features nichts anfangen konnten. Was bitteschön hat ein Listener-Object oder Templates im Bereich Systemprogrammierung verloren?

Aber auch die Nachfolger von C++ haben diese Fehler wiederholt. Java wurde entwickelt in der Hoffnung man könnte C++ einfacher machen. Also die Sprache reduzieren auf wenige Elemente die sich gut zum Unterrichten eigenen. Das war ein Fehler, es hat nicht funktioniert. Java konnte sie nicht durchsetzen. Im Grunde ist Java noch schlimmer als C++. Mit C++ konnte man zumindest noch mächtige Anwendungen schreiben, mit Java kann man nur noch Bildschirmschoner programmieren.

Vielfach ist zu lesen, dass C++ im Bereich Spielentwicklung das Nonplus-Ultra wäre. Doch in Wahrheit sind Routinen wie OpenGL ausnahmslos in C geschrieben, kommen also ohne OOP Features aus. Was hingegen richtig ist, dass man in der Spieleprogrammierung beides benötigt: sehr schnellen Code und Klassen. Einerseits benötigt man Bibliotheken die auf maximale Framezahl pro Sekunde hin optimiert wurden, gleichzeitig muss man aber auch in Lua High-Level-Scripte erstellen die Objektorientiert funktionieren. Im Grunde ist es jener Spagat der schon zur Entwicklung von C++ durch Bjarne Stroustrup’geführt hat. Zu glauben, man könne beide Anforderungen mit nur einer Programmiersprache erfüllen ist eine Illusion. Es ist nicht möglich eine Sprache zu haben, die einerseits kompiliert aber gleichzeitig auch gescriptet wird, die einerseits OOP kann gleichzeitig aber auch effizient ist. Und schaut man sich einmal gängige Spieleprojekte an, so wird das dort mit C++ auch nicht erreicht. Das heißt, in der Realität kommt eben kein C++ zum Einsatz, sondern C++ wird nur als Glue-Sprache genutzt um einerseits auf Lowlevel C Routinen zuzugreifen, gleichzeitig aber auch um GUIs zu programmieren.

C vs. Python
Vergleichen wir einmal diese beiden Programmiersprachen: C ist eine kompilierte systemnahe Sprache ohne objektorientierte Features, während Python eine interpretierte High-Level-Sprache mit objektorientierten Features ist. Beide Sprachen sind in ihrer Domäne einzigartig. Wichtig zu erwähnen ist, dass zwischen objektorientiert und kompiliert und sehr großer Unterschied besteht. Das heißt, man kann nur eines davon haben.

Die eigentliche Idee hinter der Zweiteilung aus C und Python besteht darin, dass man den Softwareentwicklungsprozess in Layer aufteilt. Also einen Raum definiert der eine Grenze besitzt und bis wo man programmiert. Das heißt, die Welt von C endet an einer bestimmten Stelle, das heißt, der C Programmierer sagt irgendwann dass er für bestimmte Dinge nicht mehr zuständig ist. Dafür werden dann andere Programmierer mit anderen Programmiersprachen benötigt. Und diese Layer Architektur macht Sinn. Damit kann man Komplexität reduzieren.

Was ich an dieser Stelle propagieren möchte ist sich eine Welt vorzustellen die ohne C++ und ohne Java auskommt. Wo man also eine Entscheidung treffen muss und nicht mit einer Sprache alle Probleme lösen kann.

Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s