경고 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
}