using enums for flags

Jonathan M Davis jmdavisProg at gmx.com
Wed Jan 25 16:01:14 PST 2012


On Wednesday, January 25, 2012 03:22:03 Trass3r wrote:
> So I was just reading
> http://stackoverflow.com/questions/1448396/how-to-use-enums-as-flags-in-c
> 
> And did a quick test:
> 
> enum STC
> {
> 	A = 0x1,
> 	B = 0x2,
> 	C = 0x4
> }
> enum FOO
> {
> 	F = 0x8,
> 	G = 0x10
> }
> 
> void main()
> {
> 	STC s = STC.A | STC.C;
> 	STC s2 = s & STC.A;
> 	auto s2_2 = s & STC.A;
> 	static assert(is(typeof(s2_2) == STC));
> 
> 	static assert(!__traits(compiles, { if (s & FOO.F) {} }));       //
> fails. that one's hard to track down
> 	static assert(!__traits(compiles, { auto s3 = s & FOO.F; }));    //
> fails, cause implicitly converts to int
> 	static assert(!__traits(compiles, { STC s4 = s & FOO.F; }));
> 	static assert(!__traits(compiles, { FOO s5 = s & FOO.F; }));
> 
> 	static assert(!__traits(compiles, { STC t = STC.A | FOO.F; }));
> 	static assert(!__traits(compiles, { auto t = STC.A | FOO.F; })); // fails
> 
> 	static assert(!__traits(compiles, { if (s & STC.B == 0) {} }));  //
> works, but error not gagged
> 	static assert(!__traits(compiles, { if (s && STC.B) {} }));      // fails
> }
> 
> Does it really make sense to allow bitwise operations on different enums?
> There should at least be some way to get this straight without having to
> resort to a heap of code like in C++:
> http://www.artima.com/cppsource/safelabels.html

I think that it makes sense to use enums as flags, but I do _not_ think that it 
makes sense to use an enum as the type of the variable _holding_ the flags.

STC var = STC.A & STC.B;

is an abimination IMHO. adding another enum to the list and doing something 
like

STC var = STC.A & FOO.F;

just makes it worse. It should be something like

uint var = STC.A & FOO.F;

instead. Now anding two different enums like that is still a bit weird, but I 
don't know that it should really be illegal. It's assigning anded enums to an 
enum that I want to see die. I'd _love_ it if that were illegal.

For instance, std.socket uses flag enums, which is fine, but in some places it 
uses them as the type of function parameters, which is _not_ a good idea IMHO. 
Whenever I think about it, I keep meaning to go and fix it, but I never get 
around to it.

- Jonathan M Davis


More information about the Digitalmars-d mailing list