简体   繁体   中英

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

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, ie 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.

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM