警告 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 个。 然而,它不会检查表的大小是否通过适当的闰年检查进行了调整,因此是一个低置信度警告。