0

I observed some behavior relating to enum structs and compound operators that I don't understand (yet). When using an enum struct as a flag, I'd like to write stuff like flag &= enum_name::What. However, depending on the compilation this either works or does not.

Here's the code I used for testing:

#include <iostream>
#include <type_traits>

enum struct A : unsigned
{
    Zero  = 0x01,
    One   = 0x02,
    Two   = 0x04,
};

A operator&(A a, A b)
{
    typedef std::underlying_type<A>::type uchar;
    return A(uchar(a) & uchar(b));
}

A& operator&=(A &a, const A b)
{
    return a = A(std::underlying_type<A>::type(a) & std::underlying_type<A>::type(b));
}

std::ostream& operator<<(std::ostream &stream, const A a)
{
    switch (a) {
        case A::Zero:
            stream << "Zero";
            break;
        case A::One:
            stream << "One";
            break;
        case A::Two:
            stream << "Two";
            break;
        default:
            stream << "Unknown";
    }
    return stream;
}

bool test(A a)
{
    return std::underlying_type<A>::type(a);
}

int main() 
{
    A flag;
    flag &= A::One;
    if (test(flag & A::One)) {
        std::cout << "flag is A::One\n";
    }
    else {
        std::cout << "flag is " << flag << "\n";
    }

    return 0;
}

Regardless of the compiler (clang 14.0.6 or g++ 12.2.0), the above code emits either "flag is A::One" or "flag is Unknown" every third or fourth compilation. It also does not matter if the values start at 0x00 instead of 0x01.

Is the reason for this behavior because A flag is not initialized on line 47? And if this is the case, is there any way to define how enum structs are "default initialized"?

rochus
  • 1

0 Answers0