bit-level logic operations on enums

Era Scarecrow rtcvb32 at yahoo.com
Fri Mar 1 14:24:22 PST 2013


On Friday, 1 March 2013 at 21:27:25 UTC, Steven Schveighoffer 
wrote:
> Then, when determining the type of an enum operation, if the 
> two operands are of the same enum type (meaning, they haven't 
> gone through any integer promotion), the result is the same 
> enum type.
>
> So this unintuitively results in:
>
> enum A : int { a }
> enum B : byte { b }
>
> A a;
> B b;
> writeln(typeof(a | a).stringof); // => A
> writeln(typeof(b | b).stringof); // => int (byte is promoted to 
> int)
> writeln(typeof(a | b).stringof); // => int
> writeln(typeof(a | 1).stringof); // => int
> writeln(typeof(b | 1).stringof); // => int

  The only way the first makes sense is the compiler knows that 
it's the same value and is a no-op, thereby doesn't lose it's 
enum state; At which case b|b should do the same thing. However 
I'm quite sure the following is true, as otherwise it wouldn't 
make sense (Unless it knows the enum can only ever be 0 and 
doesn't matter?)

   writeln(typeof(a | A.a).stringof); // => int
   writeln(typeof(A.a | a).stringof); // => int

> I would push for one of 4 behaviors, which make some sense to 
> me:
>
> 1. Math operations between two enum values of the same type 
> ALWAYS result in the same enum type regardless of base type 
> (like int-based enums)

  Isn't this the same (or close enough) as 4?

> 2. Math operations between two enum values of the same type 
> ALWAYS result in the base type (full-scale enforcement of "enum 
> only contains values from the identified list")

> 3. Operations between two enums or between an enum and an int, 
> that result at compile-time in a valid member of the enum 
> result in the enum type.  Otherwise, the operation is converted 
> to the base type.

  It might be okay to do it against compile-time known values as 
it can then confirm if the value is even possible, but this seems 
inconsistent, and can then break code if the enums values change.

> 4. Enums can be assigned any value from its base type, or any 
> value implicitly convertible to that base type.

  Then 'final switch' won't work, nor could you know if the value 
was valid at any point and enums would be easy to abuse.

> As it stands now, the compiler makes a half-assed attempt to 
> prevent invalid enum values, but fails miserably in some cases, 
> and is overzealous in others, which is in fact worse than 
> either one alone!  At this point, you can't say anything about 
> enums that is always valid except the manifest-constant usage 
> of them.
>
> TDPL is puzzlingly silent on enum math.

  Regardless it should likely be consistent with how it handles 
math and binary operators and enums.


More information about the Digitalmars-d mailing list