Search code examples
c++enumslanguage-lawyerbitwise-operators

Why do scoped enums allow use of | operator when initializing using previously assigned values?


I'm converting unscoped enumerations to scoped enumerations, and have run across a puzzle.

Stroustrup, C++ Programming Language, 4th edition, Section 8.4.1, documents that scoped enum classes are not implicitly converted to integral types, and provides code for operators | and & as an example of how to use static_cast to work around that.

Shouldn't the following initialization using the | operator on previously defined enum values be illegal?

enum class FileCopy {
    PreviousHDUs   = 1,
    CurrentHDU     = 2,
    FollowingHDUs  = 4,
    AllHDUs        = PreviousHDUs | CurrentHDU | FollowingHDUs,
    CurrentHeader  = 8
};

int main()
{
    std::cout << static_cast<int>( FileCopy::AllHDUs) << "\n";
}

I've tested this on Wandbox using both clang & gcc HEAD with --pedantic-errors, and it compiles and returns the expected output, 7. That's not to say it's legal, just that it seems to be accepted by the compilers.

Is this explicitly documented behavior? I've been unable to parse the documentation in a way that describes this behavior.


Solution

  • [dcl.enum]/5:

    ... If the underlying type is fixed, the type of each enumerator prior to the closing brace is the underlying type ...

    That is, each enumerator has type int until the closing brace is encountered. After that point, the enumerators have type FileCopy and you would not be able to bitwise-OR them together like this anymore.