Warning C6393

A lookup table of size 365 isn't sufficient to handle leap years

This rule was added in Visual Studio 2022 17.8.

Remarks

In the Gregorian calendar, every year exactly divisible by four is a leap year--except for years that are exactly divisible by 100. The centurial years are also leap years if they're exactly divisible by 400.

A leap year bug occurs when software doesn't account for this leap year logic, or uses flawed logic. The can affect reliability, availability, or even the security of the affected system.

Lookup tables of size 365 are often used to quickly find the month a given day corresponds to. However, it isn't correct because a leap year has 366 days.

Code analysis name: LEAP_YEAR_INVALID_DATE_KEYED_LOOKUP

Example

The following code creates a lookup table for the day of the year, assuming 365 days per year. However, this doesn't work if the year is a leap year:

 
#include <vector> 
  
void foo(int year) 
{ 
    const std::vector<int> items(365);  // C6393 
    // Initialize items and use it... 
}

To fix the problem, adjust the size of the lookup table as the table is created according to the result of appropriate leap year check:

#include <vector> 
  
void foo(int year) 
{ 
    bool isLeapYear = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); 
    const std::vector<int> items(isLeapYear ? 366 : 365); 
    // Initialize items and use it... 
}

Heuristics

This rule is enforced by checking if a constant lookup table is sized for 365 elements. Violation of this rule causes a high confidence warning to be reported.

See also

C6394
C26861
C26862
C26863
C26864