"Don" <[email protected]> wrote in message news:[email protected]... > > I think there might be some low-hanging fruit, though. > Supposed we distinguished enums containing AssignExpressions from those > which do not. > It seems clear to me that logical operations should always be permitted on > enums where every member of the enum has been explicitly assigned a value. > enum Enum1 { A = 1, B = 2, C = 4 } > ---> A|B makes sense. > > But if there are no assign expressions at all: > enum Enum2 { A, B, C } > then I think that performing arithmetic on that enum is almost certainly a > bug. > > The case where only some of the enum members have assign expressions is > less clear. Some cases, such as synonyms { A, B, C=B } aren't really any > different from the no-assign expression case. But other cases are less > clear, so I'll just ignore them all. So I propose a simple rule: > > Suppose that implicit integral conversions (and arithmetic/logical > operations) involving enums were permitted ONLY if the enum has at least > one AssignExpression. > > This would catch some bugs, without (I think) causing much pain for valid > code. At the very least, this is something I'd want in a lint tool. (But > note that it wouldn't fix the issue in the original post). >
If I understand that right, I think that side-steps what I see as the important goal: To *have* an associated value with each enum member but just have to be explicit about obtaining it. The above scheme doesn't really bring things significantly closer to that, you have to make a choice between type-safety and being able actually have an underlying value at all. So when you need an associated value but you're not doing bitfields/flags (which is a situation I find to be very common for enums), then that solution provides no improvement over the current state. 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. Certainly not ideal, but it provides far more type-safety than we currently have on non-bitfield/non-flag enums, even if you're using associated values, and still allows enums to be used for bitfields/flags without any code breakage or ugly "cast(int)Foo.a | cast(int)Foo.b".
