Поделиться через


Предупреждение C26474

Не приведение между типами указателей, если преобразование может быть неявным.

Основные рекомендации по C++
Тип.1. Избегайте приведения

В некоторых случаях неявные приведения между типами указателей безопасны и не требуют написания определенного выражения приведения. Это правило находит экземпляры ненужных приведения, которые можно безопасно удалить.

Замечания

Идентификатор правила должен быть интерпретирован как "Неявный приведение не используется, где это допустимо".

Это правило применимо только к указателям. Он проверяет статические приведения и переосмысление приведения.

Эти случаи являются допустимыми преобразованиями указателей, которые не должны использовать явные выражения приведения:

  • преобразование в 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
}