Skip to content

Should gsl::narrow/gsl::narrow_cast be usable *only* with arithmetic types? #1845

@dmitrykobets-msft

Description

@dmitrykobets-msft

Hi,

Is it intended for gsl::narrow_cast<T>(u) and gsl::narrow<T>(u) to only be usable with arithmetic types (so both T and the type of u must be arithmetic)?

In the current GSL implementation, gsl::narrow<T>(u) is being guarded by std::enable_if std::is_arithmetic<T>, but gsl::narrow_cast<T>(u) has no such guards. In fact, gsl::narrow_cast is essentially a wrapper around static_cast.

The guard on gsl::narrow<T>(u) prevents T from being non-arithmetic. Furthermore, the implementation of gsl::narrow will cause the code to fail to compile if static_cast<U>(narrow_cast<T>(u)) != u (where U is the type of u) is not valid. Together with the guard on T, this should prevent non-arithmetic types from being used for either of T or U. However, cases like the following actually slip through. This case does not result in a narrowing implicit/explicit conversion.

struct A
{
    A() {}
    A(int) {}
    operator int() { return 42; }
};
int main() {
    A a{42};
    gsl::narrow_cast<int>(a); // compiles and executes with no failures/errors
}

Thanks,
Dmitry

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions