Can an out-of-range enum conversion produce a value outside the underlying type?

11,378

I think [expr.static.cast]/10 answers this. In the current working draft, this reads:

A value of integral or enumeration type can be explicitly converted to a complete enumeration type. The value is unchanged if the original value is within the range of the enumeration values (7.2). Otherwise, the behavior is undefined.

In other words, your program has undefined behaviour, since the range of an enumeration type with fixed underlying type (in your case: bool) is the range of that type.

The change from your quote was affected by the resolution of CWG1766 (issues link); note that the issue is recognized as a defect (so you should forget the original wording).

Share:
11,378

Related videos on Youtube

M.M
Author by

M.M

Professional C programmer for 21 years, mostly on embedded systems. Some Windows C++ development also.

Updated on September 16, 2022

Comments

  • M.M
    M.M over 1 year

    Consider the following:

    #include <iostream>
    
    enum class E : bool { A, B };
    
    void foo(E e)
    {
        switch(e)
        {
        case E::A: break;
        case E::B: break;
        default: std::cout << "aha\n";
        }
    }
    
    int main()
    {
        foo( static_cast<E>(3) );
    }
    

    My question is: Can the default case be triggered, i.e. this program generates output?

    The tricky point in N3936 seems to be the specification of static_cast when converting an out-of-range integer to enumeration type, [expr.static.cast]/10:

    A value of integral or enumeration type can be explicitly converted to an enumeration type. The value is unchanged if the original value is within the range of the enumeration values. Otherwise, the resulting value is unspecified (and might not be in that range).

    The bolded text does not explicitly say that the value must still be within the range of the underlying type, but I am wondering if it were intended that it did.

    • M.M
      M.M over 8 years
      Note: I don't intend to restrict my question to specifically this example - if possible, an answer that also covers enums of non-fixed underlying type would be great
    • T.C.
      T.C. over 8 years
      This is UB by CWG 1766.
    • Niall
      Niall over 8 years
      Yes it could, given the cast it undefined. At least VS2013 does indeed print "aha"
    • Kerrek SB
      Kerrek SB over 8 years
      See also this question.