On Monday, 3 June 2013 at 02:23:18 UTC, Andrej Mitrovic wrote:
Let's say you define an enum, which is to be used as a variable:
enum Machine
{
X86,
X86_64,
}
So off you go and let the users (or yourself) use this in code:
-----
void main()
{
Machine machine;
...
callSomething(machine);
}
-----
And here's the problem: the enum variable was
default-initialized to
the first value. This could either be deliberate, or in many
other
cases it could be an issue of forgotten initialization.
If it's the latter, then this might become a problem. For
example, a
library writer could update the enum and inject a new enum
member at
the first position (before X86). This would update any
default-initialized enums in user-code to become something
else, and
this may cause logical bugs.
Because of this, what I usually do when I define enums is to
inject an
"Invalid" member as a sentinel at the first position of the
enum:
enum Machine
{
Invalid, // sentinel
X86,
X86_64,
}
Then, if the user really does forget to initialize the enum I
will
make sure I throw an exception when I run a `final switch` on
the enum
variable in the functions I provide (when I encounter the
Invalid
sentinel). However, the user would have to do this in his own
functions as well to make everything perfectly safe.
So, the above doesn't really scale.
What I propose is to add the ability to mark an enum somehow
(e.g.
with a "required initializer attribute"), so the user will have
to
manually initialize the enum instead of relying on
default-initialization. Default-initialization would fail to
compile
for this type of enum.
Think of it as the mirror feature of "@disable this" of
structs. To
provide an example:
@RequireInit enum Machine
{
X86,
X86_64,
}
void main()
{
// Machine machine; // compile-time error: Machine cannot
be
default-initialized
Machine machine = Machine.X86_64; // ok, explicitly
initialized
}
Thoughts?
Sounds like the exact same feature as "@disable this()" but for
enums, so perhaps it would be better to follow that syntax?