www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - enums are not distinct types?

reply "Kris" <fu bar.com> writes:
struct Foo
{
        enum X {a, b, c};
        enum Y {x, y, z};

        private X x;
        private Y y;

        static Foo f = {x : X.a, y : X.b};
}


Expected the above to fail on the assignment of X.b into member y, but it 
compiled without a peep. Are all enums considered to be of equivalent type, 
or are they distinct?
Nov 12 2005
parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
The type of an enum is defined in its declaration:

enum X: int
{
	a,
	b,
	c,
}

The default (if this is omitted) is int, as per enum.html:

The EnumBaseType is the underlying type of the enum. It must be an 
integral type. If omitted, it defaults to int.

Currently, enums seem to be treated more or less like aliases of their 
base type, but with different properties.  For example, this also works 
fine:

enum X
{
	a,
	b,
	c,
}
enum Y
{
	x,
	y,
	y,
}

int main()
{
	X test = Y.z;

	return 0;
}

I think part of this is because you might have:

enum LibraryEnum
{
	x,
	y,
	z,
}

enum ExtensionEnum
{
	x_ext,
	y_ext,
}

For an example of this, see the way Subverion's source uses and extends 
APR's enums.  Personally, I think it would be better like this:

enum ExtensionEnum: LibraryEnum
{
	x_ext,
	y_ext,
}

That is, when the EnumBaseType is another enum, possible values (and 
inheritance like with classes) is passed along, such that a LibraryEnum 
may be used as an ExtensionEnum.  For the reverse, explicit casting 
would be necessary.

But, anyway, I'm not sure where in the spec the current functionality is 
defined as wrong (or, really, right, so much...) so I'm not sure this is 
really a bug, nay?

However, what I do see as a bug is that this code compiles:

typedef int int1;
typedef int int2;

enum e1: int1
{
	v1,
}
enum e2: int2
{
	v2,
}

int main()
{
	e1 test1 = e2.v2;
	int1 test2 = e2.v2;

	// Does not work: (and shouldn't!)
	//int2 test3 = e2.v2;
	//int1 test4 = test3;

	// Also works, but probably a separate issue:
	int1 test5 = int2.init;

	return 0;
}

-[Unknown]


 struct Foo
 {
         enum X {a, b, c};
         enum Y {x, y, z};
 
         private X x;
         private Y y;
 
         static Foo f = {x : X.a, y : X.b};
 }
 
 
 Expected the above to fail on the assignment of X.b into member y, but it 
 compiled without a peep. Are all enums considered to be of equivalent type, 
 or are they distinct?
Nov 12 2005
parent "Kris" <fu bar.com> writes:
Thanks! Very useful. This should be added to the DMD documentation :-)

- Kris

"Unknown W. Brackets" <unknown simplemachines.org> wrote in message 
news:dl6b6k$12i4$1 digitaldaemon.com...
 The type of an enum is defined in its declaration:

 enum X: int
 {
 a,
 b,
 c,
 }

 The default (if this is omitted) is int, as per enum.html:

 The EnumBaseType is the underlying type of the enum. It must be an 
 integral type. If omitted, it defaults to int.

 Currently, enums seem to be treated more or less like aliases of their 
 base type, but with different properties.  For example, this also works 
 fine:

 enum X
 {
 a,
 b,
 c,
 }
 enum Y
 {
 x,
 y,
 y,
 }

 int main()
 {
 X test = Y.z;

 return 0;
 }

 I think part of this is because you might have:

 enum LibraryEnum
 {
 x,
 y,
 z,
 }

 enum ExtensionEnum
 {
 x_ext,
 y_ext,
 }

 For an example of this, see the way Subverion's source uses and extends 
 APR's enums.  Personally, I think it would be better like this:

 enum ExtensionEnum: LibraryEnum
 {
 x_ext,
 y_ext,
 }

 That is, when the EnumBaseType is another enum, possible values (and 
 inheritance like with classes) is passed along, such that a LibraryEnum 
 may be used as an ExtensionEnum.  For the reverse, explicit casting would 
 be necessary.

 But, anyway, I'm not sure where in the spec the current functionality is 
 defined as wrong (or, really, right, so much...) so I'm not sure this is 
 really a bug, nay?

 However, what I do see as a bug is that this code compiles:

 typedef int int1;
 typedef int int2;

 enum e1: int1
 {
 v1,
 }
 enum e2: int2
 {
 v2,
 }

 int main()
 {
 e1 test1 = e2.v2;
 int1 test2 = e2.v2;

 // Does not work: (and shouldn't!)
 //int2 test3 = e2.v2;
 //int1 test4 = test3;

 // Also works, but probably a separate issue:
 int1 test5 = int2.init;

 return 0;
 }

 -[Unknown]


 struct Foo
 {
         enum X {a, b, c};
         enum Y {x, y, z};

         private X x;
         private Y y;

         static Foo f = {x : X.a, y : X.b};
 }


 Expected the above to fail on the assignment of X.b into member y, but it 
 compiled without a peep. Are all enums considered to be of equivalent 
 type, or are they distinct? 
Nov 13 2005