An idea (Re: Implicit enum conversions are a stupid PITA)

Regan Heath regan at netmail.co.nz
Thu Mar 25 11:41:29 PDT 2010


Nick Sabalausky wrote:
> Here's the low-hanging fruit I see:
> 
> Step 1: Remove implicit enum->base-type conversions
> Step 2: Allow '|' (and maybe '&'?) on enums, and consider the result of the 
> operation be the base type.

I would prefer the result of Step 2 to be the enum type, not the base 
type(*)

The typical case I see for enums as flags is passing a combination of 
them to a function, where the parameter (for type-safety & 
self-documentation) will probably be of the enum type.

However, it occurs to me we don't actually get full type safety unless 
we also ensure the enum never has a value outside those defined, or a 
combination thereof(*)

Example:

enum Flags
{
   A = 0x1,
   B = 0x2,
   C = 0x4,
   D = 0x8
}
//
// possible values for a variable of type 'Flags'
// 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA
// 0xB, 0xC, 0xD, 0xE, 0xF
//
// values < 0x1 and > 0xF are illegal
//
// default value of variable of type 'Flags' is 0x1 (A)
//

<incomplete code snippets..>

void foo(Flags f) {}    //accepts only legal values for Flags

foo(Flags.A|Flags.B);  //ok
foo(0x10);             //error

Flags f;               //ok, f = 0x1
Flags err = 0x10;      //error

foo(Flags.A|0x10);     //error

</incomplete code snippets..>


(*) Some operators would return the base type, take ~ for example, it 
naturally produces a value outside the range of values defined by the 
enum type.

It follows that operators like |[=], &[=] etc would need to accept enum 
and base types as operands, otherwise some common idioms would be 
illegal, eg.

Flags f = Flags.A|Flags.B|Flags.C;
f &= ~Flags.A; // remove Flags.A from 'f'

R



More information about the Digitalmars-d mailing list