Bug 14950 – Setting enum value to the last member of another enum causes int overflow error
Status
RESOLVED
Resolution
FIXED
Severity
minor
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2015-08-23T01:09:00Z
Last change time
2015-09-01T08:21:49Z
Keywords
diagnostic, pull
Assigned to
nobody
Creator
initrd.gz
Comments
Comment #0 by initrd.gz — 2015-08-23T01:09:14Z
I encountered this when writing interfaces for a C library.
Code sample:
enum A {
start,
end
}
enum B {
start = A.end,
end
}
> rdmd -main ./test.d
./test.d(9): Error: enum member test.B.end initialization with (B.start + 1) causes overflow for type 'int'
Failed: ["dmd", "-main", "-v", "-o-", "./test.d", "-I."]
Comment #1 by k.hara.pg — 2015-09-01T04:29:07Z
This is a minor diagnostic issue.
In D, a derived enum type cannot overflow the value range of its base type.
http://dlang.org/enum
> If there is no AssignExpression and it is not the first EnumMember, it is given the value of the previous EnumMember+1. If the value of the previous EnumMember is EnumBaseType.max, it is an error. If the value of the previous EnumMember+1 is the same as the value of the previous EnumMember, it is an error. (This can happen with floating point types.)
With the definition of A and B
> enum A {
> start,
> end
> }
>
> enum B {
> start = A.end,
> end
> }
The base type of B is implicitly deduced to A, because B.start is defined by using A.end.
So B.end is beyond the value of A.max (== A.end), and compiler reports an overflow error.
But current error message is a little confusing. The current message
> ./test.d(9): Error: enum member test.B.end initialization with (B.start + 1) causes overflow for type 'int'
should become:
./test.d(9): Error: enum member test.B.end initialization with (B.start + 1) causes overflow for type 'A'
----
To avoid the error, you need to specify the base of each enum types explicitly.
You're intended that the two enums are for C library interfaces, so the best for that would be int.
A fixup example:
enum A : int {
start, // == int(0)
end // == int(1)
}
enum B : int {
start = A.end, // == cast(int)A.end == int(0)
end // == int(1)
}
Then, the B definition never overflows from its base type range: 0 to int.max.