경고 C6394
365 크기의 조회 테이블은 윤년을 처리하기에 충분하지 않습니다.
이 규칙은 Visual Studio 2022 17.8에 추가되었습니다.
설명
그레고리오력에서는 매년 정확히 4개로 나눌 수 있으며, 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으로 확장할 수 있습니다. 그러나 테이블의 크기가 적절한 윤년 검사를 통해 조정되었는지 여부를 확인하지 않으므로 신뢰도가 낮은 경고입니다.