Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The flaw in the code occurs when days has the value 366 because the loop never terminates. This bug manifested itself on the 366th day of 2008, which was the first leap year in which this code was active.

Code Block
bgColor#FFCCCC
#define ORIGINYEARfinal static int ORIGIN_YEAR = 1980;
UINT32 days = /* number of days since January 1, 1980 */
int year = ORIGINYEARORIGIN_YEAR;
/* ... */

while (days > 365) {
  if (IsLeapYear(year)) {
    if (days > 366) {
      days -= 366;
      year += 1;
    }
  }
  else {
    days -= 365;
    year += 1;
  }
}

...

This proposed rewrite is provided by http://www.aeroxp.org/2009/01/lesson-on-infinite-loops. The loop is guaranteed to exit, as days decreases for each iteration of the loop, unless the while condition fails, and the loop terminates.

Code Block
bgColor#ccccff
#define ORIGINYEARfinal static int ORIGIN_YEAR = 1980;
UINT32 days = /* input parameter number of days since January 1, 1980 */
int year = ORIGINYEAR;
/* ... */

int daysThisYear = (IsLeapYear(year) ? 366 : 365);
while (days > daysThisYear) {
  days -= daysThisYear;
  year += 1;
  daysThisYear = (IsLeapYear(year) ? 366 : 365);
}

...