View mode: basic / threaded / horizontal-split · Log in · Help
January 26, 2012
strong enums: why implicit conversion to basetype?
I thought it'd be good to outsource this question from the other 
thread about enums as flags.

Is there any merit in having implicit conversion to the basetype?
Imo it only introduces a severe bug source and brings no 
advantages.

For example it allows implicit conversion to bool.

enum Bla
{
   S1 = 1,
   S2,
   S3
}
if (Bla.S2) // makes no sense at all, all Blas convert to true
// and if S1 was 0, it would mean false, but it isn't meant as a 
special member!

A better example is something like
if (b && Bla.S2) // written '&&' instead of '&' by mistake, will 
silently pass


In general it allows operations that don't make any sense.

if (Bla.S2 & Blub.S1) // works cause an int is produced
// but by using named enums I made clear that Bla and Blub are 
totally different

Heck even +,-,... work.

Remember that if you do need to do such crazy stuff you can still 
explicitly cast to int or whatever.
January 26, 2012
Re: strong enums: why implicit conversion to basetype?
On Thursday, 26 January 2012 at 14:45:02 UTC, Manfred Nowak wrote:
> Trass3r wrote:
>
>> but by using named enums I made clear that Bla and Blub are 
>> totally different
>
> No. Obviously you decjlared both to be implicitely convertable 
> to a common super type: int. To change this, both supertypes 
> have be changed.

No. The intention is "Bla and Blub don't have anything to do with 
each other".
That's why I question the implicit conversion.
January 26, 2012
Re: strong enums: why implicit conversion to basetype?
Trass3r wrote:

> Is there any merit in having implicit conversion to the basetype?

Yes. Otherwise it would be at least close to equivalence to a 
`typedef'.

-manfred
January 26, 2012
Re: strong enums: why implicit conversion to basetype?
Trass3r wrote:

> That's why I question the implicit conversion.

Yes. I realized my fault and canceled my message, but wasn't fast 
enough.

-manfred
January 26, 2012
Re: strong enums: why implicit conversion to basetype?
>> Is there any merit in having implicit conversion to the 
>> basetype?
>
> Yes. Otherwise it would be at least close to equivalence to a 
> `typedef'.

Even typedef implicitly converts in one of the directions.
A named enum is a separate type with a finite set of allowed 
values defined by the user.
January 26, 2012
Re: strong enums: why implicit conversion to basetype?
Trass3r wrote:


> Even typedef implicitly converts in one of the directions.

`typedef' is or will be disallowed in D because of reasons I do not 
understand. In C and C++ their existence introduce problems because 
they increase the amount of parsing passes. 


> A named enum is a separate type with a finite set of allowed 
> values defined by the user.
A)
Both wrong according to the currently published reference:

1) "The enum EnumTag declares a new type, and all the EnumMembers have 
that type.", i.e. it is the tag not the hole enum that produces a new 
type. 
2) "Enum declarations are used to define a group of constants.", i.e. 
only some of the valid values of the basetype are given names. All of 
the valid values of the basetype are also valid in the type declared 
by the tag.
3) "An EmptyEnumBody signifies an opaque enum - the enum members are 
unknown", i.e. none of the valied values of the basetype has got a 
name, but all valid values of the basetype are also valid in the type 
declared by the tag.

B)
It is somehow difficult to write about the reference because the use 
of the terms declaration, definition or declaration follows rules, 
which I have not yet detected.

I use "declaration" for any entity, which is undefined at the current 
position of reading _and_ will be defined after that position is 
passed. This is often an identifier in D.  

I use "definition" for any entity, which represents the content of the 
transition from undefined to defined. This is often a type in D. 

I use "specification" for those two entities, which represents a 
binding between a declaration and a definition. This is often the 
absence of operators in D.

-manfred
January 26, 2012
Re: strong enums: why implicit conversion to basetype?
On 01/26/2012 02:59 PM, Trass3r wrote:
> I thought it'd be good to outsource this question from the other thread
> about enums as flags.
>
> Is there any merit in having implicit conversion to the basetype?
> Imo it only introduces a severe bug source and brings no advantages.
>
> For example it allows implicit conversion to bool.
>
> enum Bla
> {
> S1 = 1,
> S2,
> S3
> }
> if (Bla.S2) // makes no sense at all, all Blas convert to true
> // and if S1 was 0, it would mean false, but it isn't meant as a special
> member!

That is not an implicit conversion. if(x) is equivalent to if(cast(bool)x).


>
> A better example is something like
> if (b && Bla.S2) // written '&&' instead of '&' by mistake, will
> silently pass
>
>
> In general it allows operations that don't make any sense.
>
> if (Bla.S2 & Blub.S1) // works cause an int is produced
> // but by using named enums I made clear that Bla and Blub are totally
> different
>
> Heck even +,-,... work.
>
> Remember that if you do need to do such crazy stuff you can still
> explicitly cast to int or whatever.

I have argued for banning those operations on strong enums before, but 
some objected to it because they wanted to use strong enums as bit flags.
January 26, 2012
Re: strong enums: why implicit conversion to basetype?
Le 26/01/2012 14:59, Trass3r a écrit :
> I thought it'd be good to outsource this question from the other thread
> about enums as flags.
>
> Is there any merit in having implicit conversion to the basetype?
> Imo it only introduces a severe bug source and brings no advantages.
>
> For example it allows implicit conversion to bool.
>
> enum Bla
> {
> S1 = 1,
> S2,
> S3
> }
> if (Bla.S2) // makes no sense at all, all Blas convert to true
> // and if S1 was 0, it would mean false, but it isn't meant as a special
> member!
>
> A better example is something like
> if (b && Bla.S2) // written '&&' instead of '&' by mistake, will
> silently pass
>
>
> In general it allows operations that don't make any sense.
>
> if (Bla.S2 & Blub.S1) // works cause an int is produced
> // but by using named enums I made clear that Bla and Blub are totally
> different
>
> Heck even +,-,... work.
>
> Remember that if you do need to do such crazy stuff you can still
> explicitly cast to int or whatever.

I don't see any problem with that : it is perfectly safe. The other way 
around isn't and isn't allowed, so the current behaviour seems fine to me.
January 26, 2012
Re: strong enums: why implicit conversion to basetype?
> I have argued for banning those operations on strong enums before, but  
> some objected to it because they wanted to use strong enums as bit flags.

Yep, that's what the other thread 'using enums for flags' is about.
But implicit conversions seem wrong in any case.
January 26, 2012
Re: strong enums: why implicit conversion to basetype?
> `typedef' is or will be disallowed in D because of reasons I do not
> understand.

It's ill-defined. There are 4 possible types of typedef:  
http://d.puremagic.com/issues/show_bug.cgi?id=5467

> In C and C++ their existence introduce problems because
> they increase the amount of parsing passes.

C's typedef is equal to D's alias.

>> A named enum is a separate type with a finite set of allowed
>> values defined by the user.
> A)
> Both wrong according to the currently published reference:

Again, this thread is all about discussing the right way to do it and not  
about what the buggy and holey spec reads.

> 2) "Enum declarations are used to define a group of constants.", i.e. 
> only some of the valid values of the basetype are given names. All ofthe  
> valid values of the basetype are also valid

That's what anonymous enums are for.

> 3) "An EmptyEnumBody signifies an opaque enum - the enum members are
> unknown", i.e. none of the valied values of the basetype has got a
> name, but all valid values of the basetype are also valid in the type
> declared by the tag.

So the only purpose is to create a new type similar to typedef.
I don't see any merit in that.
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home