Thursday, January 5, 2023

History: writing fancy code on a plain compiler (Irix version)

 Writing fancy code on a plain compiler

This is a story of porting C++ code using all the latest features to a machine whose compiler was (ahem) definitely not supportive of advanced features :-/

Back in about 1997 and 1998 I was a software consultant and got hired by an old coworker at Avid to help them port their shiny new high-performance file-copying software to the Irix. IIRC, they had written it in “portable” C++ which I discovered was anything but

Writing code with no strings attached

 Amongst the other delights of 1997 era SGI workstations: SGI was a leader in creating the C++ STL. But the SGI people really, really didn’t like the proposed STL string types, so they just … didn’t. One of the many, many steps on my journey to porting this code was to create enough of a string class to compile.

 Other issues were that vector<> wasn’t compatible either, so I had some lovely #ifdef’s in the code.

What's in a namespace? Nothing. 

 The compiler also didn’t handle namespaces; they were read in an ignored. For most code this was a minor inconvenience, but the people writing this “portable” C++ code were a different breed. They had many, many classes with the same name and similar but different functionality. My solution was to create enough of a C++ “parser” to re-write the code. Turns out that if you ignore enough of the rules, you can make a C++ parser with just Lex 😊

Exceptionally fine threading

 But the absolute worst part was that the “portable” C++ code used both multiple threads (typical for networking code) and exceptions (still a new thing). The SGI compiler (which was the only compiler – I did a thorough look to find anybody else with a compiler) could handle threads, and could handle exceptions, but created incorrect binaries when dealing with both. And it didn’t matter if you threw any exceptions; the generated code was wrong regardless.

 My simple solution was to note that every single exception was uniformly caught exactly one level higher, and that none of their code ever returned a value. So I just made the exception-throwing methods return a value, instead. Simple, quick to implement and IMHO made the code a little nicer looking. This solution was rejected.

 The alternative solution was to use processes instead of threads. A “thread spawn” became a “process spawn”. And not just a process spawn: a process spawn all of the processes sharing their C++ memory so the data structures should be shared (and mutually updated, meaning using cross-process mutexes).

 This was an unglodly heavyweight project. But the pay was very nice.


 Moral of the story: never outrun your compiler?

No comments: