Sdílet prostřednictvím


Upozornění C26474

Nepřetypovávejte mezi typy ukazatelů, pokud by převod mohl být implicitní.

Pokyny pro C++ Core:
Type.1: Vyhněte se přetypování

V některých případech jsou implicitní přetypování mezi typy ukazatelů bezpečné a nevyžadují zápis konkrétního výrazu přetypování. Toto pravidlo najde instance nepotřebných přetypování, které můžete bezpečně odebrat.

Poznámky

ID pravidla by se mělo interpretovat jako implicitní přetypování, které se nepoužívá tam, kde je přijatelné.

Toto pravidlo se vztahuje pouze na ukazatele. Kontroluje statické přetypování a reinterpretuje přetypování.

Tyto případy jsou přijatelné převody ukazatelů, které by neměly používat explicitní přetypování výrazů:

  • převod na nullptr_t;
  • převod na void*;
  • převod z odvozeného typu na jeho základ při vyvolání základní členské funkce, která není skryta odvozeným typem.

Příklad 1

Nepotřebný převod skryje v tomto příkladu chybu logiky:

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)) {
            // ...
        }
    }
}

Příklad 2

Tento příklad ukazuje použití přetypování pro přístup k členským funkcím základní třídy:

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
}