...
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 | ||
---|---|---|
| ||
#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 | ||
---|---|---|
| ||
#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); } |
...