C26474 NO_IMPLICIT_CAST

"Don't cast between pointer types when the conversion could be implicit."

C++ Core Guidelines: Type.1: Avoid casts

In some cases, implicit casts between pointer types can safely be done and don’t require user to write specific cast expression. This rule finds instances of such unnecessary casting which can be removed.

Remarks

  • The rule ID is a bit misleading: it should be interpreted as "implicit cast is not used where it is acceptable".
    • The rule is applicable to pointers only and checks static casts and reinterpret casts.
    • The following cases are acceptable pointer conversions that should not use explicit cast expressions:
    • conversion to nullptr_t;
    • conversion to void*;
    • conversion from derived type to its base.

Example

unnecessary conversion hides logic error

template<class T>
bool register_buffer(T buffer) {
    auto p = reinterpret_cast<void*>(buffer); // C26474, also 26490 NO_REINTERPRET_CAST
    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)) {
            // ...
        }
    }
}

unnecessary conversion hides logic error - reworked

// ...
template<class T>
bool register_buffer(T *buffer) {
    auto p = buffer;
    return buffers_.insert(p).second;
}
// ...