Condividi tramite


Avviso C26474

Non eseguire il cast tra tipi di puntatore quando la conversione potrebbe essere implicita.

Linee guida di base per C++:
Type.1: Evitare i cast

In alcuni casi, i cast impliciti tra tipi di puntatore sono sicuri e non richiedono la scrittura di un'espressione cast specifica. Questa regola trova istanze di cast non necessari che è possibile rimuovere in modo sicuro.

Osservazioni:

L'ID regola deve essere interpretato come "Un cast implicito non viene usato dove è accettabile".

Questa regola è applicabile solo ai puntatori. Controlla i cast statici e reinterpreta i cast.

Questi casi sono conversioni di puntatori accettabili che non devono usare espressioni cast esplicite:

  • conversione in nullptr_t;
  • conversione in void*;
  • conversione da un tipo derivato alla relativa base quando si richiama una funzione membro di base non nascosta dal tipo derivato.

Esempio 1

Una conversione non necessaria nasconde un errore di logica in questo esempio:

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

Esempio 2

Questo esempio illustra l'uso di cast per accedere alle funzioni membro della classe base:

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
}