경고 C26474
변환이 암시적일 수 있는 경우 포인터 형식 간에 캐스팅하지 마세요.
C++ 핵심 지침:
Type.1: 캐스트 방지
경우에 따라 포인터 형식 간의 암시적 캐스트는 안전하며 특정 캐스트 식을 작성할 필요가 없습니다. 이 규칙은 안전하게 제거할 수 있는 불필요한 캐스트의 인스턴스를 찾습니다.
설명
규칙 ID는 "허용되는 경우 암시적 캐스트가 사용되지 않습니다."로 해석되어야 합니다.
이 규칙은 포인터에만 적용됩니다. 정적 캐스트를 확인하고 캐스트를 재해석합니다.
이러한 경우는 명시적 캐스트 식을 사용하지 않아야 하는 허용 가능한 포인터 변환입니다.
- 로
nullptr_t
변환 - 로
void*
변환 - 파생 형식에서 숨겨지지 않은 기본 멤버 함수를 호출할 때 파생 형식에서 해당 기본 형식으로 변환합니다.
예 1
불필요한 변환은 이 예제에서 논리 오류를 숨깁니다.
template<class T>
bool register_buffer(T buffer) {
auto p = reinterpret_cast<void*>(buffer); // C26474, also 26490 NO_REINTERPRET_CAST
// To fix, declare buffer as T*, and use this to define p:
// auto p = buffer;
return buffers_.insert(p).second;
}
void merge_bytes(std::uint8_t *left, std::uint8_t *right)
{
if (left && register_buffer(*left)) { // Unintended dereference!
// ...
if (right && register_buffer(right)) {
// ...
}
}
}
예제 2
이 예제에서는 캐스트를 사용하여 기본 클래스 멤버 함수에 액세스하는 방법을 보여 줍니다.
struct struct_1
{
void foo();
void bar();
};
struct struct_2 : struct_1
{
void foo(); // this definition hides struct_1::foo
};
void fn(struct_2* ps2)
{
static_cast<struct_1*>(ps2)->foo(); // This cast is necessary to access struct_1::foo
// Alternatively, use ps2->struct_1::foo();
static_cast<struct_1*>(ps2)->bar(); // This cast is unnecessary and can be done implicitly
}