Range of enum type values

Timon Gehr timon.gehr at gmx.ch
Fri Dec 27 14:12:39 UTC 2019

On 27.12.19 13:14, Johan Engelen wrote:
> Current compiler behavior results in an infinite value range. (but it's 
> implicit behavior, i.e. not explicitly mentioned in spec)
> - Currently, are operations resulting in a value larger than the 
> underlying integer storage type UB,

They are @safe. You can't have UB in @safe code.

> like for normal signed integers?

Signed integers have wraparound semantics.

The spec mentions this for AddExpressions (but the example only shows it 
for uint): https://dlang.org/spec/expression.html
"If both operands are of integral types and an overflow or underflow 
occurs in the computation, wrapping will happen."

There simply _can't_ be any UB in signed integer operations, as they are 
considered @safe.

> - Should we limit the range of valid values of the Flags enum (C++ 
> defines valid range to be [0..7])?
> - Do we want to limit operations allowed on enum types? Or change the 
> result type? (e.g. the type of `Flags + Flags` is `int` instead of `Flags`.

I see those options:

1. The valid range is the full range of the underlying type (as DMD 
treats it now).

2. The range is [1..4]. In this case, the operations have to promote 
their operands to the enum base type, and most casts to enum types must 
be @system.

3. The range is [0..7]. In this case, only operations that preserve this 
range (such as bitwise operators) should yield the enum type, and other 
operations should promote their operands to the enum base type, and most 
casts to enum types must be @system.

Personally, I think 2 makes most sense (especially with `final switch`, 
as the current semantics forces compilers to insert default cases 
there), but this would be a breaking language change.

More information about the Digitalmars-d mailing list