Jump to page: 1 2
Thread overview
strong enums: why implicit conversion to basetype?
Jan 26, 2012
Trass3r
Jan 26, 2012
Trass3r
Jan 26, 2012
Manfred Nowak
Jan 26, 2012
Manfred Nowak
Jan 26, 2012
Trass3r
Jan 26, 2012
Manfred Nowak
Jan 26, 2012
Trass3r
Jan 26, 2012
Manfred Nowak
Jan 26, 2012
Timon Gehr
Jan 26, 2012
Trass3r
Jan 26, 2012
deadalnix
Jan 26, 2012
Don
Jan 26, 2012
Trass3r
Jan 27, 2012
Don Clugston
Jan 27, 2012
Trass3r
Jan 26, 2012
Alvaro
Jan 26, 2012
Manfred Nowak
Jan 27, 2012
Simen Kjærås
Jan 27, 2012
Chad J
Jan 27, 2012
Simen Kjærås
January 26, 2012
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
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
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
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
>> 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
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
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
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
> 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
> `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