Porting Unix code to Windows

07 July 2010
It was a quiet time in the office as the hardware I needed for what I was supposed to do had not arrived, and the directors were away so I had no other assigned tasks. Decided to take the opportunity to do a code cleanup, and port the code to Windows. Many of the pitfalls I was already aware of as it was hardly the first time I've ported Unix code, but it does make a good excuse to rant about it..

Winsock Irritations

Even though Windows Sockets is based on BSD sockets, there are subtle incompatibilities that are complete headaches, as they involve littering #ifdefs all over code that otherwise requires minimal changes for just about every other operating system I am likely to ever use. Most of these seem to stem from Unix using the same interface for non-socket things and this in turn conflicting with some fossilised design decision.

One annoying one is BSD using signed integers whereas Winsock using unsigned integers, so errors are indicated via a predefined constant rather than the sign bit. However one that really stings is functions such as read() that not only do not work for sockets, they retain the same arguments. That means rather than a compile error (or at least warning), you are bug-hunting in the inner-depths of ADTs you thought long bug-free. Result: Changing over to Microsoft's convention and adding in place-holder conditional defines for Unix platforms. And a working week spent in the process (though the latter is really a problem for my boss rather than me).

To be fair, INVALID_SOCKET & SOCKET_ERROR are both defined as 0xffffffff, which on Intel architecture systems has the same bit-pattern as -1. Although not recommended, this means Unix code that checks for -1 (unlike checking for less-than-zero) still works. Based on the impression I get from reading Old New Thing, I suspect this may have been intentional.

On the plus side..

..it is not all doom and gloom. The Win32 API has its collection of documentation holes, historical accidents and outright oddities, but as far as C-based APIs go it is pretty complete: One central message system which all notifications go through. Some of the required pointer manipulation can get hairy, but if you are afraid of pointers you should not really be using C anyway.

Another nice feature is not having to work out which of dozens of header files need to be included. I've written network programs requiring a dozen or so headers under Linux, whereas Windows required only two. Most features within the Win32 GUI have also been around quite a long time, whereas some GUI toolkits are notorious for having non-frozen interface specifications.