Der Long-Arrow-Operator – das Stiefkind der Programmierer

Eine Kritik an der mangelhaften Umsetzung eines der Standard-Operatoren in allen gängigen Programmiersprachen.

Was ist der Long-Arrow-Operator?

Die Geschichte der Softwareentwicklung hat über die Jahrzehnte viele Programmiersprachen hervorgebracht, um eine gewisse Abstraktion und Convenience bei der Verwendung von Hardware zu erreichen. Niemand mag heute mehr in Assembler auf Bit-Ebene programmieren, selbst wenn das bis heute der einzige Weg ist, um die Vorgänge auf einem Computer unter Kontrolle zu behalten.

Die meisten gängigen Programmiersprachen haben sich auf ähnliche oder sogar identische Operatorenkonzepte geeinigt. Codierungen von Standard-Operationen in den jeweiligen Programmiersprachen sind beispielsweise + für die Summenbildung, << für Bit-Shifting, < für einen Vergleich zweier Werte, und viele mehr. Eine Übersicht findet man z. B. für C# unter [1], für Visual Basic unter [2], für C++ unter [3] oder für Javascript unter [4].

Der Long-Arrow-Operator ist eine wenig bekannte Operation, die in Schleifen für eine schrittweise Annäherung von Werten aneinander sorgt, eine sogenannte iterativ-integrative Operation. Mit −−> wird dabei der linke Wert des Ausdrucks dem rechten Wert des Ausdrucks schrittweise angenähert

Wofür wird der Long-Arrow-Operator verwendet?

Der Long-Arrow-Operator kann immer dort verwendet werden, wo sich ein Variablenwert iterativ an einen anderen Wert annähern soll. Hier im Beispiel das Herunterzählen der Variablen count:

    int count = 5;
    while (count −−> 0) {
        Console::Write(count + " ");
    }

Erwartungsgemäß zählt hier die Variable von 4 bis 0 herunter. Die Ausgabe:

    4 3 2 1 0

Was ist am Long-Arrow-Operator falsch?

Alle relevanten Programmiersprachen werden heute mit der Absicht des „Principle of Least Astonishment“ gestaltet, also der geringstmöglichen Überraschung, kurz: Erwartungskonformität. In hardwarenahen Programmiersprachen haben wir uns mit der Zeit an manchen Seiteneffekt gewöhnt. Über die Jahre wurden die Programmiersprachen aber nachgebessert, um konsequent die Seiteneffekte zu beseitigen und die Sprachen an den heutigen Zeitgeist der Erwartungskonformität anzupassen.

Der Long-Arrow-Operator verhält sich jedoch vollkommen überraschend. Wir probieren den Long-Arrow in anderen Varianten, zum Beispiel in umgekehrte Richtung:

    int count = 5;
    while (0 <−− count) {
        Console::Write(count + " ");
    }

Entgegen unserer Erwartung ist die Ausgabe fehlerhaft:

    4 3 2 1

Wir wundern uns, warum hier nicht bis 0 heruntergezählt wurde, sondern die 0 vergessen wurde. Ein eindeutiger Off-by-One-Fehler in der Umsetzung im Compiler. Obendrein sind wir verwirrt, welcher Operand sich nun bewegen soll – ist es er linke Operand oder der rechte?

Noch schwerwiegender wird der Fehler, wenn der Operator nicht absteigen, sondern aufsteigen soll. Wir starten in diesem Beispiel bei einem negativen Wert:

    int count = -5;
    while (count −−> 0) {
        Console::Write(count + " ");
    }

Der Code liefert keinerlei Ergebnis. Erwartungskonformität schaut anders aus.

Der Bold-Long-Arrow-Operator

Neben dem Long-Arrow-Operator existiert zudem der Bold-Long-Arrow-Operator ++>. Hier das Beispielprogramm:

    int count = 5;
    while (count ++> 0) {
        Console::Write(count + " ");
    }

Statt count der 0 anzunähern, zählt hier das Programm munter Zahlen auf, bis wir das Programm abbrechen. Der ++>-Operator verhält sich vollkommen unlogisch.

Unser Eindruck: Idee gut, Umsetzung ungenügend

Wir sind von der Umsetzung der beiden Arrow-Operatoren mehr als enttäuscht. Nach genauerer Recherche stellen wir fest, dass die Long-Arrow-Operatoren scheinbar nur von wenigen sehr versierten Programmierern eingesetzt werden. Folglich wurde dieser Bug wahrscheinlich noch nie gemeldet oder angesichts der wenigen Nutzer als irrelevant eingeschätzt. Wir haben sicherheitshalber bei Microsoft ein Ticket öffnen lassen, um sicherzustellen, dass bei diesem Fehler nachgebessert wird.

Open Source

Wir konnten die Fehler auch mit Clang und GCC reproduzieren. Unsere Suche nach einer Hotline, an die wir den Fehler fernmündlich hätten melden können, verlief ernüchternd. Auch die Suche nach einer Briefadresse war erfolglos. Die wenigen Hotlines der großen Distributionen waren vollkommen überfordert mit der Fragestellung. Sie fragten uns nach Dingen wie „Haben Sie den Computer mal neu gestartet?“ und „Was sehen Sie auf Ihrem Bildschirm“.

Auch ein seriöses Feedback-Portal konnten wir nicht finden. Lediglich Web-Adressen [5], die von uns das Anlegen eines Accounts einforderten. Es wirkt so, als wolle man sicherstellen, dass die Fehlermeldung unter Ausschluss der Öffentlichkeit abgewickelt wird. Unsere Sicherheitsexperten stuften diese Adressen zudem als Gefahr ein. Wir fanden auch verwirrende Anleitungen [6], die von uns einforderten, dass wir uns mithilfe von komplizierten Skripten mit dem internen Aufbau des Compilers befassen, ohne uns die Möglichkeit zu geben, einfach nur einen Mangel am Produkt zu melden. Es entsteht der Eindruck, als würde hier Cancel-Culture durch die Hintertür mit Hilfe unnötig komplizierter Hürden umgesetzt.

Angesichts des Chaos und der arroganten Selbstgefälligkeit in der Open-Source-Szene sehen wir keine Chance, dass selbst ein erfolgreich übermittelter Bug Report irgendetwas bewegen könnte. Solange die üblichen Distributionen den Linux-Kernel noch irgendwie kompiliert bekommen, wird hier wahrscheinlich nichts passieren. Unsere bisherigen Erfahrungen mit Open-Source-Software lassen auch vermuten, dass die beteiligten Programmierer die Long-Arrow-Operatoren schlichtweg nicht kennen.

Fazit

Die Long-Arrow-Operatoren sind großartige Ausdrucksmöglichkeiten, mit der iterative Variablenannäherungen implementiert werden können – und das in einer Vielzahl von Programmiersprachen. Abseits vom Variablenabstieg sind leider alle anderen Anwendungsfälle in den Compilern heute unvollständig und fehlerhaft implementiert.

Wir sind ein wenig enttäuscht, dass die Long-Arrow-Operatoren unter Software-Entwicklern so unbekannt sind. Hier ist Aufklärung gefragt! Je mehr Entwickler den Long-Arrow-Operator einsetzen und die Fehlerbehebungen einfordern, desto früher werden die Long-Arrow-Operatoren in künftigen Compiler-Versionen fehlerfrei funktionieren.

Petition

Sind auch Sie der Meinung, dass die Compiler dringend nachgebessert werden müssen?

Signieren Sie hier unsere Petition: https://www.change.org/p/fix-the-long-arrow-operator