James Newton's story needs no introduction ... so ... enjoy!

My second job as a programmer was working for a defense contractor. One of the things I did there was maintaining a library of code that was being used by a few tens of projects. One day I got a bug report in saying that if a time class (some particular time system) was constructed with a large number it would hang the program in a busy loop. The number passed in was simply the number of seconds from an epoch.

The first thing I found in my debugging quest was a little over engineering. This library had pretty much every time system ever conjured up implemented as separate classes. All of these time classes had various constructors which took various different things and pretty much every time class was able to construct itself off all other time classes. Now this user had managed to find the perfect combination which caused the Solaris C++ compiler to invoke a need to be way too helpful. The type of number that he constructed this particular class with caused the compiler to choose not only one, nor two, but three chained automatic promotions without being prompted to. This number got filtered through 3 different time classes before coming to rest in the intended time system. Needless to say this number was far beyond useless by the time it got to its final resting place.

Thats rather unusual, but without that compiler behavior the program hang would have never been found. I had assumed the code involved (which for the large part worked pretty well) would not invoke anything that would cause blocking. All its doing is a little math to convert a number, right? Well after stepping through a debugger I managed to find where it got hung up. It was a seemingly innocent for loop that went like this (please forgive me while I reconstruct it from memory:

int value, divisor;

int result=value/divisor;
int remainder=value;
while ( remainder != 0)
{
  if (remainder>divisor)
    remainder=remainder-divisor;
  else
    break;
}

'value' was the input number (heavily filtered as it may have been) and at the end of this loop i was what was desired. I simply could not believe my own eyes. Someone had implemented a subtraction loop to find the remainder of a division. As you might have guessed from having code to handle every time system ever, time was very important to the overall task at hand and these time classes were used simply everywhere. I cant imagine the number of cpu cycles that were saved by replacing all of that code with:

int result=value/divisor;
int remainder=value%divisor;
[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!