Aviso C6394
Uma tabela de pesquisa de tamanho 365 não é suficiente para lidar com anos bissextos
Essa regra foi adicionada no Visual Studio 2022 17.8.
Comentários
No calendário gregoriano, cada ano exatamente divisível por quatro é um ano bissexto - exceto para anos que são exatamente divisíveis por 100. Os anos centuriais também são anos bissextos se forem exatamente divisíveis por 400.
Um bug de ano bissexto ocorre quando o software não dá conta dessa lógica de ano bissexto ou usa lógica falha. Isso pode afetar a confiabilidade, a disponibilidade ou até mesmo a segurança do sistema afetado.
Tabelas de pesquisa de tamanho 365 são frequentemente usadas para encontrar rapidamente o mês ao qual um determinado dia corresponde e assim por diante. No entanto, não é correto porque um ano bissexto tem 366 dias.
Nome da análise de código: LEAP_YEAR_INVALID_DATE_KEYED_LOOKUP_MUTABLE
Exemplo
O código a seguir cria uma tabela de pesquisa para o dia do ano, mas pressupõe que haja 365 dias por ano. No entanto, isso produz o resultado errado ou pode causar um acesso fora dos limites da tabela de pesquisa, se o ano for um ano bissexto:
#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.
}
Para corrigir esse problema, ajuste o tamanho da tabela de pesquisa como a tabela é criada de acordo com o resultado de uma verificação de ano bissexto:
#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...
}
Heurística
Essa regra é imposta verificando se uma tabela de pesquisa tem um tamanho inicial de 365 elementos, mas pode ser expandida para 366. No entanto, ele não verifica se o tamanho da tabela é ajustado por meio de verificação de ano bissexto adequado ou não, e por isso é um aviso de baixa confiança.