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.

Confira também

C6393
C26861
C26862
C26863
C26864