I’ve been working on porting some open source code to Windows CE recently and ran into something which got me thinking about portable code, and thinking ahead when designing/implementing something.
Consider the Windows programming API. It provides both ANSI and Unicode versions of its API functions. The base API call is mapped to the correct version at compile time via preprocessor #defines. For example, CreateFile is mapped to CreateFileA and CreateFileW depending on if UNICODE is defined or not. The difference being, of course, that the filename argument varies in the size of it’s character array (char * vs. w_char *).
Now lets say some code directly references the ANSI version, because they aren’t concerned about Unicode and wide chars. This is fine and dandy until you try to port to a WINCE SDK that doesn’t include the ANSI versions in its core libraries. One or two instances of this aren’t that big of an issue, but chances are if a developer did this once, the practice has been reproduced throughout the code base. A portability nightmare.
The problem above is easily solved by calling the base API call, and creating a typedef for a base character array element which is dependent on the same preprocessor #define that Windows keys off of.
I would argue it is rare, especially when dealing with open source, to work on a piece of code that won’t be modified from it’s intended purpose or ported to a different platform by someone you will never interact with. An extra 30 minutes spent on thoughtful design creates much more portable code. This spares future developers working on the code base countless hours and headaches (which, hopefully, they pay forward through good design)!