Aracılığıyla paylaş


Uyarı C26474

Dönüştürme örtük olabileceğinde işaretçi türleri arasında geçiş yapmayın.

C++ Temel Yönergeleri:
Tür.1: Tür atamalarından kaçının

Bazı durumlarda, işaretçi türleri arasındaki örtük atamalar güvenlidir ve belirli bir atama ifadesi yazmanızı gerektirmez. Bu kural, güvenli bir şekilde kaldırabileceğiniz gereksiz atama örneklerini bulur.

Açıklamalar

Kural kimliği "Örtük bir atama kabul edilebilir olduğu yerde kullanılmaz" olarak yorumlanmalıdır.

Bu kural yalnızca işaretçiler için geçerlidir. Statik yayınları ve yeniden yorum dökümlerini denetler.

Bu durumlar, açık atama ifadelerini kullanmaması gereken kabul edilebilir işaretçi dönüştürmeleridir:

  • dönüştürme;nullptr_t
  • dönüştürme;void*
  • türetilmiş tür tarafından gizlenmeyen bir temel üye işlevi çağrılırken türetilmiş bir türden tabanına dönüştürme.

Örnek 1

Gereksiz dönüştürme, bu örnekteki bir mantıksal hatayı gizler:

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

Örnek 2

Bu örnekte, temel sınıf üye işlevlerine erişmek için atamaların kullanılması gösterilmektedir:

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
}