www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - EnumBaseType conversion

reply dsimcha <dsimcha yahoo.com> writes:
I was actually about to file this as a bug until I double checked the spec and
realized that, as ridiculous as it seems, this is correct according to the spec.

What is the rationale for allowing named enums to implicitly convert to their
EnumBaseType?  This seems like an unnecessarily dangerous feature to me (named
enums are supposed to create a distinct type, and you can always explicitly
cast them).  It has bitten me several times when I have a named enum type next
to an integer type or something that an integer can be implicitly converted to
in a function param list:

enum MyEnum {
    FOO,
    BAR
}

void doStuff(MyEnum me, int i) {}
void doRealStuff(MyEnum me, real i) {}

void main() {
    doStuff(MyEnum.BAR, MyEnum.FOO);
    doRealStuff(MyEnum.BAR, MyEnum.FOO);
}

IMHO if you want manifest constant behavior that does not create a distinct
type, that's what anonymous enums are for.  If you just want a namespace and
don't want to create a new type, you can just use a dummy struct:

struct MyEnum {
    enum FOO = 0;
    enum BAR = 1;
}
Jun 16 2009
next sibling parent reply grauzone <none example.net> writes:
There's a simple solution: don't use that failure of a language 
construct called enum, and write your own one. You simply can do 
something Java-style, where enums basically are just normal classes 
generated by the compiler frontend. In D, you can use structs, and 
string mixins can generate the appropriate fields. Something like:

struct YourEnum(char[] fields) {
	private int value;
	mixin(generatefields());
         static char[] generatefields() { return YOURMAGICHERE(fields); }
}

Enum fields are static and of the type YourEnum. e.g. 
YourEnum("FOO,BAR") would add these members to the struct:
	const YourEnum FOO = YourEnum(0);
	const YourEnum BAR = YourEnum(1);
These are generated by the CTFE function generatefields().

As long as the value field is hidden, you have enums that are even more 
typesafe than the good old Pascal counterparts. Oh, and you can easily 
add code to convert strings to enum values, too.

Walter can delete all that buggy enum code from his compiler and from 
the language specification.

 struct MyEnum {
     enum FOO = 0;
     enum BAR = 1;
 }

Gah, this abuse of the enum keyword is really outright disgusting. I also find it ironic how Walter tries to keep D C compatible (that is, C code compiled by dmd either runs correctly, or compilation fails), while such differences between D1 and D2 seem to be OK. (Examples: const, memory allocating closures, overloading rules)
Jun 16 2009
parent bearophile <bearophileHUGS lycos.com> writes:
grauzone:
 I also find it ironic how Walter tries to keep D C compatible (that is, 
 C code compiled by dmd either runs correctly, or compilation fails), 
 while such differences between D1 and D2 seem to be OK. (Examples: 
 const, memory allocating closures, overloading rules)

Walter is right here, C is used by millions of people, while D1 is kinda unknown. D1 will vanish, C will be around for some more years. So keeping compatibility with C is much more important than keeping compatibility with D1. Bye, bearophile
Jun 16 2009
prev sibling parent reply Robert Fraser <fraserofthenight gmail.com> writes:
dsimcha wrote:
 It has bitten me several times when I have a named enum type next
 to an integer type or something that an integer can be implicitly converted to
 in a function param list:
 
 enum MyEnum {
     FOO,
     BAR
 }

Try... typedef int _MyEnum; enum MyEnum : _MyEnum { FOO, BAR }
Jun 16 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
Robert Fraser:
 typedef int _MyEnum;
 enum MyEnum : _MyEnum
 {
 	FOO,
 	BAR
 }

Isn't it better for all enums to behave like this (and require a cast to be used as their base types)? Bye, bearophile
Jun 16 2009
parent "Nick Sabalausky" <a a.a> writes:
"bearophile" <bearophileHUGS lycos.com> wrote in message 
news:h18j5t$18q7$1 digitalmars.com...
 Robert Fraser:
 typedef int _MyEnum;
 enum MyEnum : _MyEnum
 {
 FOO,
 BAR
 }

Isn't it better for all enums to behave like this (and require a cast to be used as their base types)?

Yes. I also was unaware of this behavior and am rather dissapointed by it. This just smacks of the old problematic C-style weak-typing that I've spent years trying to avoid. I shouldn't need an idiom to do things the safe/correct way.
Jun 16 2009