January 20, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2524





------- Comment #10 from schveiguy@yahoo.com  2009-01-20 17:15 -------
But I can still cast to the interface.  Protection attributes are compile-time entities, they are not flagged at runtime:

SoundManager s;
Object o = s;

INetworkListener inl = cast(INetworkListener)o;

The compiler just looks in the object's list of interfaces to see if it finds that interface.  There is no protection associated with it at runtime.

What you are asking for requires a major compiler redesign for limited value. You can easily implement what you want using a private inner class:

interface INetworkListener {
    void acceptNetworkPacket();
}

class NetworkManager
{
    static void registerNetworkListener(INetworkListener listener) { ... }
}

class SoundManager
{
    private class NetworkListener : INetworkListener
    {
      void acceptNetworkPacket() {
        // ...
      }
    }

    this() {
        NetworkManager.registerNetworkListener(new NetworkListener);
    }
}

This is similar to how Java works with anonymous classes.  D can do the same thing I think, but I can't remember the syntax right now.


-- 

January 21, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2524





------- Comment #11 from 2korden@gmail.com  2009-01-21 01:10 -------
(In reply to comment #10)
> But I can still cast to the interface.  Protection attributes are compile-time entities, they are not flagged at runtime:
> 
> SoundManager s;
> Object o = s;
> 
> INetworkListener inl = cast(INetworkListener)o;
> 
> The compiler just looks in the object's list of interfaces to see if it finds that interface.  There is no protection associated with it at runtime.
> 

So what? How does this differ from the following in C++:

class A {
    void foo();
}

class B : protected A {
}

B* b = new B();
//b->foo(); // error
//A* a = b; // error
void* o = b;
A* a = (A*)o;
a->foo();

You just hijacked type system, that's it.

One possible solution would be to add protection flag into class typeinfo which will be taken into account during dynamic cast. Or remove interface from classinfo.interfaces altogether (it should still be possible to cast known class to its known base class/interface statically, i.e. without dynamic cast).

I know the issue is not of high value but it should either be fixed for consistency, or protection inheritance attributes should be removed from language.


-- 

January 21, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2524





------- Comment #12 from smjg@iname.com  2009-01-21 05:47 -------
(In reply to comment #10)
> But I can still cast to the interface.  Protection attributes are compile-time entities, they are not flagged at runtime:
> 
> SoundManager s;
> Object o = s;
> 
> INetworkListener inl = cast(INetworkListener)o;
> 
> The compiler just looks in the object's list of interfaces to see if it finds that interface.  There is no protection associated with it at runtime.

But the compiler is capable of checking to see whether the inheritance is public or private.  It just doesn't at the moment.  No runtime protection checking needed in this instance.

> What you are asking for requires a major compiler redesign for limited value.

I still think this "major compiler redesign" should be removing inheritance protection altogether.  Which would have the value of simplifying the language by getting rid of these things that don't make sense.

(In reply to comment #11)
> So what? How does this differ from the following in C++:
> 
> class A {
>     void foo();
> }
> 
> class B : protected A {
> }
> 
> B* b = new B();
> //b->foo(); // error
> //A* a = b; // error
> void* o = b;
> A* a = (A*)o;
> a->foo();

Firstly, try putting your code through a C++ compiler.

Secondly, your code goes through void*, whereby it's obvious that you're intent on subverting the type system.  Moreover, it may break if multiple inheritance is involved.

That said, as I try it C++ allows the cast straight from B* to A*, but it must be explicit.


-- 

January 21, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2524





------- Comment #13 from schveiguy@yahoo.com  2009-01-21 07:08 -------
(In reply to comment #12)
> (In reply to comment #10)
> > But I can still cast to the interface.  Protection attributes are compile-time entities, they are not flagged at runtime:
> > 
> > SoundManager s;
> > Object o = s;
> > 
> > INetworkListener inl = cast(INetworkListener)o;
> > 
> > The compiler just looks in the object's list of interfaces to see if it finds that interface.  There is no protection associated with it at runtime.
> 
> But the compiler is capable of checking to see whether the inheritance is public or private.  It just doesn't at the moment.  No runtime protection checking needed in this instance.
> 

Casting to Object is valid, since the class did not inherit from Object privately.  Once you get to object, you need runtime information to cast to a subclass or interface.  If you're suggesting that an optimization can "see" that the object originated from a SoundManager instance, then I can easily generate a case where the cast to object and the cast to the interface are hidden in opaque functions, eliminating the possibility of optimization.

I still contend that this cannot be checked at compile-time.

(In reply to comment #11)
> So what? How does this differ from the following in C++:
> 
> [snip]
>
> You just hijacked type system, that's it.

No, I did not.  Casting to an Object is a legal move within the type system. It is equivalent to casting to a base class.  Casting to an interface is also a legal move, it is like a C++ dynamic_cast to a derived class.  There is no hijacking going on.

> 
> One possible solution would be to add protection flag into class typeinfo which will be taken into account during dynamic cast. Or remove interface from classinfo.interfaces altogether (it should still be possible to cast known class to its known base class/interface statically, i.e. without dynamic cast).

I'm not sure this is possible, but I don't know completely the inner workings of an interface cast.  I think it's required that the interface vtable be present in the class instance, and I think it's probably also required that it be in the classinfo.

> I know the issue is not of high value but it should either be fixed for consistency, or protection inheritance attributes should be removed from language.

I would agree wholeheartedly that inheritance protection should be disallowed for interfaces.  I am not sure about inheritance protection for the base class, I've never used it, and the documentation is completely absent (save for the mention that it's valid syntax).  I can't see a use case that couldn't be solved by composition, or using private inner classes.


-- 

January 21, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2524





------- Comment #14 from smjg@iname.com  2009-01-21 07:53 -------
(In reply to comment #13)
>> But the compiler is capable of checking to see whether the inheritance is public or private.  It just doesn't at the moment.  No runtime protection checking needed in this instance.
> 
> Casting to Object is valid, since the class did not inherit from Object privately.  Once you get to object, you need runtime information to cast to a subclass or interface.

Sorry, I misread what your code was doing.  It's the same as the C++ example indeed.


-- 

January 23, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=2524


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com


--- Comment #15 from Walter Bright <bugzilla@digitalmars.com> 2012-01-22 21:27:32 PST ---
This is a compiler bug. You can override an interface function.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 23, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=2524



--- Comment #16 from github-bugzilla@puremagic.com 2012-01-22 21:57:09 PST ---
Commit pushed to https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/f595bde35576dd0165dd0e0964d478c7db31955a fix Issue 2524 - final override inconsistent when implementing interfaces

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 23, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=2524


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
1 2
Next ›   Last »