One thing that's biting me currently is imposed version number formatting. The product I'm working on uses the traditional Major-Minor-Patch format, that is, there are three numerical components in a version number. Additionally, we add a suffix for special builds based on a previous release, such as a single letter for a hotfix build, or a service pack identifier, or a support ticket identifier.
Getting software certified for Windows Vista necessitates including a manifest with the software that, among other information, contains the name of the executable, the version number, security settings, and a signature. The version number consists of four components: Major, minor, build and revision. The version number goes into an XML attribute, so one programmer apparently forgot to double-check and put in our regular three-component version number.
Needless to say, we figured that out fairly fast, since Windows 2003 will refuse to run applications with embedded manifests that contain errors. Interestingly, the tool that actually embeds the manifest doesn't comment at all. And the error that you get from Windows is not very transparent - you have to look into the system event log to get a clue, and unless you're on Vista, the clue you're getting is only that there's something wrong with your manifest. Anyway, we just added a zero as the fourth component and all was well.
Over time, we started to use an 1 instead of a 0 as the fourth component for a revision based on a previous release.
Some time later, we figured out that we actually have multiple different types of revisions. So now, the fourth component is calculated from all of them (or, all of those that we thought of, so far). It's starting to look like a bit field. Of course, the "revision" field is completely meaningless for comparison purposes: Revision 100 is based on completely different changes to the source code than Revision 1. Granted, you can still tell from revision 101 that it includes both sets of updates, but at this point I'm just glad that our other platforms aren't as limiting.
It should be an offense to rely on the size of a given type in C to be the same across different platforms. Still, certain assumptions appear to be fairly common. One of them is the value of sizeof(long). I think we've gotten over the idea that long and int are the same size now that 64 bit platforms are becoming more and more common. However, occassionally I still encounter a similar misconception: That the sizes of long and any pointer type are the same.
1 #include <stdio.h>
2 #define S(X) printf(#X " %d\n", sizeof(X))
3
4 int main() {
5 S(int *);
6 S(long);
7 return 0;
8 }
This snippet will tell you that both a long and a pointer to int are of size 4 on most 32 bit platforms, and that both are of size 8 on most 64 bit platforms. There is one notable platform where this isn't the case. When compiled with Visual Studio's cl.exe on 64 bit Windows, the size of the pointer will be 8, but the size of the long will be 4.
According to the C standard, this is perfectly legal. In reality, I've seen variables of type long used to store pointers, or anything else that fits into a long on one of the other platforms. Please stop doing that, it's wrong, and it will break on Windows.