OpenWatcom C/C++

Der OpenWatcom C/C++ Compiler zählt nicht nur zu den ältesten seiner Art, er unterstützt auch noch die alten Plattformen wie Windows 3.X, OS/2 und DOS neben Linux und WinNT.

Und er ist wahrlich “antiquiert” in Sachen Standards und std Support.
Kurz gesagt: Genau die richtige Umgebung für meine Experimente.


Vor etwas über 10 Jahren wollte ich schon einmal mit diesem Compiler “ins Gespräch” kommen, doch da ich CMake noch nicht kannte, wurden diese Pläne wieder auf Eis gelegt.

Watcom C und C++ war offenbar recht beliebt im vergangenen Jahrtausend, bevor Windows und Linux im Jahr 2000 so richtig durchstarteten. Denn mit seiner Anbindung an die DOS-Extender APIs ermöglichte er 32-Programmierung unter DOS und war nebenbei recht beliebt bei den Spiele-Entwicklern. Meine uralten Lieblinge wie DOOM, Duke Nukem 3D und Tomb Raider wurden mit diesem Compiler übersetzt.

2003 wurde Watcom C auf Open-Watcom umgetauft und kostenfrei verfügbar. So lernte ich Version 1.9 etwa um 2010 kennen.
Inzwischern wurde ein Fork 2.0 abgespalten, der aber bis heute noch im Beta-Stadium ist und stückweise weiterentwickelt wird.

Eigenheiten von OpenWatcom

  • Keine Function-Template Spezialisierungen.
    Template Klassen und Strukturen können halbwegs normal spezialisiert werden. Man kann auch rein generische Template-Funktionen schreiben, aber dort führen Spezialisierungsversuche sofort zu Fehlern.
  • Kein vollständiges SFINAE
    Also z.B. kein enable_if. Der Compiler lässt ungültige Template Konstellationen also nicht weg (wie im Standard gefordert), sondern generiert Fehler.
  • Im Default keine nicht-globalen C struct Initialisierung erlaubt.
    struct mystruct myvar = { var1, 2, 3.0 }; innerhalb einer Funktion lehnt der Compiler mal einfach so ab. Nur globale konstante Instanziierungen sind erlaubt. Das kann man zum Glück durch die Compiler Option -aa ändern.
  • Keine anonymen union Instanzen.
    Ich nutze ja gerne union in einem struct und erwarte dann, dass jeder union Member wie ein Teil der struct ansprechbar ist. Doch in Watcom muss ein Instanzname benutzt werden. Das merkt man übelst, wenn man viel Code mit COM VARIANT Typen hat und die Kurzschreibweise erwartet.
  • Moderne Header sind zwar vorhanden, tragen aber nur wenige Zeilen mit dem Inhalt
    1/* TODO: Implement me! */
    

    in sich. Also kein C++11 oder C11 Support trotz existierender Header.

Und vieles mehr wird sich wahrscheinlich bei weiteren Experimenten noch ergeben.

CMake support für WMAKE

Ich hatte anfangs den schweren Fehler gemacht, dass ich absichtlich mit einer älteren CMake-Variante experimentiert hatte um 32-bit EXEn zu erzeugen.

Doch der CMake-Support für OpenWatcom ist über die Jahre viel besser geworden und während ich mit der alten Version scheiterte, hatte ich keine Probleme, den Windows 64-bit Compiler mit der neuesten Version von CMake dazu zu bekommen 32-Bit NT-Binaries auszuwerfen.

CMake erzeugt dafür wmake-Files, die mit dem wmake Tool ganz analog zum normalen make Compiler und Linker Aufrufe durchführen um Projekte zu bauen. Man muss also nur ins Build-Verzeichnis springen und wmake eintippen um einen Build-Prozess loszutreten.

OpenWatcom kommt auch mit einer eigenen IDE, eigenem Debugger und eigenem Projekt-Format. Aber ich ziehe es vor, alles über CMake laufen zu lassen. Und als Editor kann man schließlich immer auf Visual Studio Code zurückgreifen.

Fazit

Mein nächstes Ziel ist kein Geheimnis: DOS.

Ich frage mich, was notwendig ist, um die Codebase des GATE-Projektes für DOS kompilierbar zu machen. Klar ist, dass viele Systemfunktionen, die aktuell nur für Win32 und POSIX implementiert sind, noch krass angepasst werden müssen. Aber generische Array, Map und Encoding Routinen (wie XML, JSON usw.) sollten hoffentlich out-of-the-box laufen … außer die DOS-Speichersegmente behindern meine aktuell gesetzten Puffergrößen.

Genau hier wird es spannend, wie man Code so schreiben kann, dass er sich dynamisch an die Plattform anpasst.

Die Spiele mögen beginnen.