I tend to save writing for instances where I find something humorous that I can cross-reference. I actually do not have a lot of humor to offer this time, but having worked through our 64-bit port in the last few months I do have a few interesting observations that are worth sharing. Also, my manager asked if I would write something, and assured me that something noteworthy must have occurred during the 64-bit port. He also mentioned that it should not involve any of the colorful string of adjectives that came out of of my cubical during that period of time. It occurs to me as I write this that he might ask this again, so I’ve gone with the “Volume 1″ naming scheme… of course if I never write about this topic again it wouldn’t be the first time that something named “Volume 1″ is never followed up with a “Volume 2″.
As we began the 64-bit port we faced the same challenges as any company dealing with a large established code base. A lot of typing issues. In the 64-bit world, long means different things on different platforms. In some cases it doesn’t make any difference, in others it does. These cases have to be carefully examined. In some cases the solution was not to use long at all. There were cases where we had used long because it seemed like the right thing to do, but on careful examination, int is completely sufficient.
However, the most interesting case we came up against was a call to the X-Windows library. The specific call had looked like this for years:
XtVaSetValues(xftXtTopLevelShell, XtNx, -1000, XtNy, -1000, XtNwidth, 100, XtNheight, 100, XtNmappedWhenManaged, False, 0);
And it was fine in our initial builds and testing. But as we approached our first beta and started to compile our release configuration, the editor would crash on this line. I spent an evening trying different compiler options, and different versions of the compiler, because I simply did not see a problem with this line. But there is one.
The functions that start with XtVa take a variable number of arguments. In this case, that last argument – the ’0′ – is a pointer. On a 32-bit system, a pointer is 32-bits wide, and an int is 32-bits wide. So passing 0 works just fine. On a 64-bit system, pointers are 64-bits wide, and NULL is a 64-bit unsigned number. 0, however, is a 32-bit signed number. Which actually works fine… until you turn on compiler optimizations.
Here is the corrected code:
XtVaSetValues(xftXtTopLevelShell, XtNx, -1000, XtNy, -1000, XtNwidth, 100, XtNheight, 100, XtNmappedWhenManaged, False, NULL);
This wasn’t the most confusing problem I encountered, in fact I’m sure to a seasoned 64-bit Linux guru it should not have a been a problem at all. But it was one of the things I felt was interesting enough to share here.
This article was reposted from the SlickEdit blog.