警告 C6394

大小为 365 的查找表不足以处理闰年

此规则是在 Visual Studio 2022 17.8 中添加的。

备注

在公历中,每个能被 4 整除的年份都是闰年,但能被 100 整除的年份除外。 如果百年年份能被 400 整除,那么它们也是闰年。

当软件未考虑此闰年逻辑或使用有缺陷的逻辑时,就会出现闰年 bug。 这可能会影响相关系统的可靠性、可用性甚至安全性。

大小为 365 的查找表通常用于快速查找给定日期对应的月份,等等。 但是,这不是正确的,因为闰年有 366 天。

代码分析名称:LEAP_YEAR_INVALID_DATE_KEYED_LOOKUP_MUTABLE

示例

以下代码将为一年中的某一天创建一个查找表,但其假定每年有 365 天。 然而,如果年份是闰年,这会产生错误的结果,或者可能导致对查找表的边界外访问:

#include <vector> 
  
void foo(int year) 
{ 
    std::vector<int> items(365);  // C6394 
    // Initialize items and use it... 
    // Another item may be added to the vector if year is a leap year, but this
    // rule doesn't check if that is the case.
}

若要解决此问题,请在创建查找表时根据闰年检查的结果来调整该表的大小:

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

启发

此规则是通过以下方式强制实施的:检查查找表的初始大小是否为 365 个元素,但可以扩展到 366 个。 然而,它不会检查表的大小是否通过适当的闰年检查进行了调整,因此是一个低置信度警告。

另请参阅

C6393
C26861
C26862
C26863
C26864