Advertencia C26474
No convertir entre tipos de puntero cuando la conversión podría ser implícita.
C++ Core Guidelines:
Type.1: Evitar conversiones
En algunos casos, las conversiones implícitas entre tipos de puntero son seguras y no requieren que escriba una expresión de conversión específica. Esta regla busca instancias de conversiones innecesarias que se pueden quitar de forma segura.
Comentarios
El identificador de regla debe interpretarse como "No se usa una conversión implícita donde es aceptable".
Esta regla solo se aplica a punteros. Comprueba las conversiones estáticas y reinterpreta las conversiones.
Estos casos son conversiones de puntero aceptables que no deben usar expresiones de conversión explícitas:
- conversión a
nullptr_t
; - conversión a
void*
; - conversión de un tipo derivado a su base al invocar una función miembro base que no está oculta por el tipo derivado.
Ejemplo 1
Una conversión innecesaria oculta un error lógico en este ejemplo:
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)) {
// ...
}
}
}
Ejemplo 2
En este ejemplo se muestra el uso de conversiones para acceder a funciones miembro de clase 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
}