Skip to content

SafeCast with enumeration and expected truncation fails #62

Open
@jacobl-at-ms

Description

@jacobl-at-ms

Up front, Trying to use SafeInt to cast to an enum seems like something that should be rejected at compile time to me (possibly through the use of static_assert but I can also see an argument to look at the underlying storage size. What I didn't expect was to see the enum get through to std::numeric_limits<> which just returned 0.

Example I have is:

#include "SafeInt.hpp"
#include <cstdint>
#include <iostream>

enum MyEnum : int {
};

int main(uint64_t argc)
{
    MyEnum x;
    std::cout << "SafeCast(u, tT): " << SafeCast(argc, x) << "\n";
    return 0;
}

compiled with:

cl /std:c++20 /nologo /Wall /EHsc /Zi example.cpp

prints:

prompt>example.exe
SafeCast(u, tT): 0

The "problem" seems to be that std::numeric_limits<> on an enum type will always return 0/false even if it could safely cast the value.

When I step into the debugger I see this stack:

>	example.exe!SafeCastHelper<enum MyEnum,unsigned __int64,2>::Cast(unsigned __int64 u, MyEnum & t) Line 1115	C++
 	example.exe!SafeCast<unsigned __int64,enum MyEnum>(const unsigned __int64 From, MyEnum & To) Line 5385	C++
 	example.exe!main(unsigned __int64 argc) Line 11	C++

and we end up returning in this block:

        if( u > (U)std::numeric_limits<T>::max() )
            return false;

because max() returns 0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions