Поделиться через


Предупреждение C6394

Таблица подстановки размером 365 недостаточно для обработки високосных лет

Это правило было добавлено в Visual Studio 2022 17.8.

Замечания

В григорианском календаре каждый год точно делится на четыре високосный год, за исключением лет, которые точно делятся на 100. Вековые годы также високосные годы, если они точно делятся на 400.

Ошибка високосного года возникает, когда программное обеспечение не учитывает логику этого високосного года или использует несовершенную логику. Это может повлиять на надежность, доступность или даже безопасность затронутой системы.

Таблицы подстановки размера 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