警告 C6394
サイズ 365 のルックアップ テーブルでは、閏年を処理するには不十分です
この規則は、Visual Studio 2022 17.8 で追加されました。
解説
グレゴリオ暦では、毎年 4 で正確に割り切れる年は閏年です。ただし、100 で正確に割り切れる年を除きます。 百年も閏年は、400 で正確に割り切れる場合です。
閏年のバグは、ソフトウェアがこの閏年ロジックを考慮しない場合、または欠陥のあるロジックを使用する場合に発生します。 信頼性、可用性、または影響を受けるシステムのセキュリティに影響を与える可能性があります。
サイズ 365 のルックアップ テーブルは、多くの場合、特定の日が対応する月をすばやく検索するために使用されます。 ただし、閏年には 366 日があるため、正しくありません。
コード分析名: LEAP_YEAR_INVALID_DATE_KEYED_LOOKUP_MUTABLE
例
次のコードでは、年の日の参照テーブルを作成しますが、1 年あたり 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 に拡張できます。 ただし、テーブルのサイズが適切な閏年チェックによって調整されているかどうかは確認されず、低信頼度の警告も表示されます。