Range of enum type values

Steven Schveighoffer schveiguy at gmail.com
Fri Dec 27 14:58:59 UTC 2019


On 12/27/19 9:12 AM, Timon Gehr wrote:
> 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.
> https://forum.dlang.org/thread/n23bo3$qe$1@digitalmars.com
> 
> 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.

We have another option, which I like. That is, only allow bitwise 
operations on enums that are flagged as allowing bitwise operations 
(either with a uda, or via some other mechanism). Many languages 
actually treat enums just like structs, where you can add operators and 
functions. This is also a possibility.

This is also a breaking change, but also I don't want the compiler 
complaining about final switch on enums where the enum is intended not 
to be a bitwise flag. So I'd prefer 2 over 3.

-Steve


More information about the Digitalmars-d mailing list