Thread overview
Associative array bug?
Jun 16, 2006
Max Samuha
Jun 18, 2006
Bruno Medeiros
Jun 19, 2006
BCS
June 16, 2006
Can interfaces be used as AA keys? The following code causes access
violation (WinXP, dmd 0.160):

interface I
{
	void method();
}

class A : I
{
	void method()
	{
	}
}

void main()
{
	I a = new A();

	int[I] array;

	array[a] = 5; // Access violation
}

When I replace the interface with a base class, it works.

abstract class I
{
	void method();
}

class A : I
{
	override void method()
	{
	}
}

void main()
{
	I a = new A();

	int[I] array;

	array[a] = 5; // Ok
}

Is it a known bug?
June 18, 2006
Max Samuha wrote:
> Can interfaces be used as AA keys? The following code causes access
> violation (WinXP, dmd 0.160):
> 
> interface I
> {
> 	void method();
> }
> 
> class A : I
> {
> 	void method()
> 	{
> 	}
> }
> 
> void main()
> {
> 	I a = new A();
> 	
> 	int[I] array;
> 
> 	array[a] = 5; // Access violation	
> }
> 
> When I replace the interface with a base class, it works.
> 
> abstract class I
> {
> 	void method();
> }
> 
> class A : I
> {
> 	override void method()
> 	{
> 	}
> }
> 
> void main()
> {
> 	I a = new A();
> 	
> 	int[I] array;
> 
> 	array[a] = 5; // Ok	
> }
> 
> Is it a known bug?

It's a bug for sure, regardless of whether interfaces can be used as AA keys. (If it is allowed, then the program shouldn't crash, if it isn't allowed the program shouldn't compile)

If it is known, I dunno, it's just a matter of searching the bugzilla.

----

Now, whether interfaces can be used as AA keys or not, it depends if we have a method to do hash from an interface. One way would be to require the interface to have a toHash method. But I'm not sure if that would make much sense.
Another way, perhaps the most sensible, would be to cast to Object and use the underlying toHash(). But that depends on whether it is allowed that an interface can be converted to a reference to it's underlying class.
The doc only says "A class that implements an interface can be converted to a reference to that interface.", but not the otherwise. However it seems that DMD does allow for an interface to be converted to a class (since that feature is what allows interface->class return type covariance to work), but that is all very not explicit and not documented.




-- 
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
June 19, 2006
Bruno Medeiros wrote:
[...]
> 
> Now, whether interfaces can be used as AA keys or not, it depends if we have a method to do hash from an interface. One way would be to require the interface to have a toHash method. But I'm not sure if that would make much sense.
> Another way, perhaps the most sensible, would be to cast to Object and use the underlying toHash(). But that depends on whether it is allowed that an interface can be converted to a reference to it's underlying class.
> The doc only says "A class that implements an interface can be converted to a reference to that interface.", but not the otherwise. However it seems that DMD does allow for an interface to be converted to a class (since that feature is what allows interface->class return type covariance to work), but that is all very not explicit and not documented.
> 
> 
> 
> 
How about using an IndexForAA interface and a mixin template to pull up the right symbols. Then all that would be need would be to have the interface inherent that interface and away you go.


// i'm working from memory here so

interface KeyForAA
{
	uint toHash();
	int opCmp(KeyForAA);
}

template KeyForAA_Mixin
{
		// pull in the defaults from Object or the super class
	alias toHash toHash;
	alias opCmp opCmp;
}