www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - broken override

reply "Mickey Finn" <horizon blackhole.net> writes:
class A
{
  protected void test()
  {
    printf ("A");
  }
}

class B
{
   private override void test()
   {
    printf ("B");
   }
}

main()
{
  B b = new B;
  b.test();
}

output: A

No compile error; nothing; Nada. Simple typing mistake while refactoring. So
much for "override" catching bugs.
Aug 04 2004
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 4 Aug 2004 17:18:30 -0700, Mickey Finn wrote:

 class A
 {
   protected void test()
   {
     printf ("A");
   }
 }
 
 class B
 {
    private override void test()
    {
     printf ("B");
    }
 }
 
 main()
 {
   B b = new B;
   b.test();
 }
 
 output: A
 
 No compile error; nothing; Nada. Simple typing mistake while refactoring. So
 much for "override" catching bugs.

I just tried your example and I get the output "B". Also, the override attribute is only meant to be used on virtual functions. I quote the manual... "The override attribute applies to virtual functions. It means that the function must override a function with the same name and parameters in a base class. The override attribute is useful for catching errors when a base class's member function gets its parameters changed, and all derived classes need to have their overriding functions updated." -- Derek Melbourne, Australia 5/Aug/04 10:40:13 AM
Aug 04 2004
parent "Stratus" <vdai spamnet.net> writes:
I also tried this example before the other version was posted. Even so, it
points out another problem with "override":  as soon as you add "private" to
the "override" method, the mechanism breaks. For example, you should not
have been able to compile without error purely because (in the bogus
example) B.test did /not/ override anything, as you pointed out. The
"private" keyword somehow disables that functionality. Same thing happens
when using the "package" keyword too. something is not right here.


"Derek Parnell" <derek psych.ward> wrote in message
news:cervok$o5k$1 digitaldaemon.com...
 On Wed, 4 Aug 2004 17:18:30 -0700, Mickey Finn wrote:

 class A
 {
   protected void test()
   {
     printf ("A");
   }
 }

 class B
 {
    private override void test()
    {
     printf ("B");
    }
 }

 main()
 {
   B b = new B;
   b.test();
 }

 output: A

 No compile error; nothing; Nada. Simple typing mistake while


 much for "override" catching bugs.

I just tried your example and I get the output "B". Also, the override attribute is only meant to be used on virtual functions. I quote the manual... "The override attribute applies to virtual functions. It means that the function must override a function with the same name and parameters in a base class. The override attribute is useful for catching errors when a base class's member function gets its parameters changed, and all derived classes need to have their overriding functions updated." -- Derek Melbourne, Australia 5/Aug/04 10:40:13 AM

Aug 04 2004
prev sibling parent reply "Mickey Finn" <horizon blackhole.net> writes:
Oops; typed up the contrived example just to illustrate the issue, but it's
a sneakier bug than first noted. Here's an example that was actually
executed:

class A
{
  protected void create()
  {
    printf ("A");
  }

  void test()
  {
        create();
  }
}

class B : A
{
   private override void create()
   {
    printf ("B");
   }
}

void main()
{
  B b = new B;
  b.test();
}

Output: A

I repeat: no compile error; nothing; nada. Simple typing mistake while
refactoring. So much for "override" catching bugs.
Aug 04 2004
parent reply Regan Heath <regan netwin.co.nz> writes:
On Wed, 4 Aug 2004 18:31:29 -0700, Mickey Finn <horizon blackhole.net> 
wrote:

 Oops; typed up the contrived example just to illustrate the issue, but 
 it's
 a sneakier bug than first noted. Here's an example that was actually
 executed:

 class A
 {
   protected void create()
   {
     printf ("A");
   }

   void test()
   {
         create();
   }
 }

 class B : A
 {
    private override void create()
    {
     printf ("B");
    }
 }

 void main()
 {
   B b = new B;
   b.test();
 }

 Output: A

 I repeat: no compile error; nothing; nada. Simple typing mistake while
 refactoring. So much for "override" catching bugs.

You know it's the fact that one method is private and the other protected, right? Were they that way in the original class, if so, wasn't it a bug there too? If not what was the point? (I have not done enough C++ to see it) Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 04 2004
parent reply "Mickey Finn" <horizon blackhole.net> writes:
"Regan Heath" <regan netwin.co.nz> wrote in message
news:opsb8lkppu5a2sq9 digitalmars.com...
 On Wed, 4 Aug 2004 18:31:29 -0700, Mickey Finn <horizon blackhole.net>
 wrote:
 You know it's the fact that one method is private and the other protected,
 right?

Yep. That's the point. If you remove the "private" it works as expected. The point is that override is meant to catch this, but didn't.
 Were they that way in the original class, if so, wasn't it a bug there
 too? If not what was the point? (I have not done enough C++ to see it)

No, they weren't. This was a classic case of "ahh, that method probably shoudn't be exposed at this level; let's make it private". However, the compiler then (a) ignored the method in B even though it should still invoke it, and (b) "override" played dumb. Further, there's the valid notion that this was deliberately attempting to restrict visibility on that particular method. But that's a different topic, because this one is about "override" not catching the issue; and that alone.
Aug 04 2004
parent reply Regan Heath <regan netwin.co.nz> writes:
On Wed, 4 Aug 2004 19:46:43 -0700, Mickey Finn <horizon blackhole.net> 
wrote:
 "Regan Heath" <regan netwin.co.nz> wrote in message
 news:opsb8lkppu5a2sq9 digitalmars.com...
 On Wed, 4 Aug 2004 18:31:29 -0700, Mickey Finn <horizon blackhole.net>
 wrote:
 You know it's the fact that one method is private and the other 
 protected,
 right?

Yep. That's the point. If you remove the "private" it works as expected.

I know. I am simply pointing out the bug might not be in 'override' itself, but in the resolution of the function call.
 The
 point is that override is meant to catch this, but didn't.

I think override _is_ working, but function resolution is not.
 Were they that way in the original class, if so, wasn't it a bug there
 too? If not what was the point? (I have not done enough C++ to see it)

No, they weren't. This was a classic case of "ahh, that method probably shoudn't be exposed at this level; let's make it private". However, the compiler then (a) ignored the method in B even though it should still invoke it

This is the bug.
 , and (b) "override" played dumb.

If you assume (a) then override was in fact correct.
 Further, there's the valid notion that this was deliberately attempting 
 to
 restrict visibility on that particular method. But that's a different 
 topic,
 because this one is about "override" not catching the issue; and that 
 alone.

Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 04 2004
parent reply "Mickey Finn" <horizon blackhole.net> writes:
Regan; Derek; I'm just trying to report a bug ... not have a
pseudo-philosophical debate. I'll leave it up to the compiler author to
determine exactly what the root cause is, and how to fix it. Is that
acceptable?


"Regan Heath" <regan netwin.co.nz> wrote in message
news:opsb8ribzv5a2sq9 digitalmars.com...
 On Wed, 4 Aug 2004 19:46:43 -0700, Mickey Finn <horizon blackhole.net>
 wrote:
 "Regan Heath" <regan netwin.co.nz> wrote in message
 news:opsb8lkppu5a2sq9 digitalmars.com...
 On Wed, 4 Aug 2004 18:31:29 -0700, Mickey Finn <horizon blackhole.net>
 wrote:
 You know it's the fact that one method is private and the other
 protected,
 right?

Yep. That's the point. If you remove the "private" it works as expected.

I know. I am simply pointing out the bug might not be in 'override' itself, but in the resolution of the function call.
 The
 point is that override is meant to catch this, but didn't.

I think override _is_ working, but function resolution is not.
 Were they that way in the original class, if so, wasn't it a bug there
 too? If not what was the point? (I have not done enough C++ to see it)

No, they weren't. This was a classic case of "ahh, that method probably shoudn't be exposed at this level; let's make it private". However, the compiler then (a) ignored the method in B even though it should still invoke it

This is the bug.
 , and (b) "override" played dumb.

If you assume (a) then override was in fact correct.
 Further, there's the valid notion that this was deliberately attempting
 to
 restrict visibility on that particular method. But that's a different
 topic,
 because this one is about "override" not catching the issue; and that
 alone.

Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/

Aug 04 2004
next sibling parent Regan Heath <regan netwin.co.nz> writes:
On Wed, 4 Aug 2004 21:39:15 -0700, Mickey Finn <horizon blackhole.net> 
wrote:
 Regan; Derek; I'm just trying to report a bug ... not have a
 pseudo-philosophical debate. I'll leave it up to the compiler author to
 determine exactly what the root cause is, and how to fix it. Is that
 acceptable?

Sure, whatever floats your boat man. Regan
 "Regan Heath" <regan netwin.co.nz> wrote in message
 news:opsb8ribzv5a2sq9 digitalmars.com...
 On Wed, 4 Aug 2004 19:46:43 -0700, Mickey Finn <horizon blackhole.net>
 wrote:
 "Regan Heath" <regan netwin.co.nz> wrote in message
 news:opsb8lkppu5a2sq9 digitalmars.com...
 On Wed, 4 Aug 2004 18:31:29 -0700, Mickey Finn 


 wrote:
 You know it's the fact that one method is private and the other
 protected,
 right?

Yep. That's the point. If you remove the "private" it works as

I know. I am simply pointing out the bug might not be in 'override' itself, but in the resolution of the function call.
 The
 point is that override is meant to catch this, but didn't.

I think override _is_ working, but function resolution is not.
 Were they that way in the original class, if so, wasn't it a bug 


 too? If not what was the point? (I have not done enough C++ to see 


 No, they weren't. This was a classic case of  "ahh, that method 

 shoudn't be exposed at this level; let's make it private". However, 

 compiler then (a) ignored the method in B even though it should still
 invoke
 it

This is the bug.
 , and (b) "override" played dumb.

If you assume (a) then override was in fact correct.
 Further, there's the valid notion that this was deliberately 

 to
 restrict visibility on that particular method. But that's a different
 topic,
 because this one is about "override" not catching the issue; and that
 alone.

Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/


-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 04 2004
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 4 Aug 2004 21:39:15 -0700, Mickey Finn wrote:

 Regan; Derek; I'm just trying to report a bug ... not have a
 pseudo-philosophical debate. I'll leave it up to the compiler author to
 determine exactly what the root cause is, and how to fix it. Is that
 acceptable?

Didn't know that's what I was doing, but hey! whatever. No skin off my knees. I still think that there is no bug and it's your attempted usage that is the issue. The docs say "virtual" functions only and you are not using it with virtual functions - so call me silly. -- Derek Melbourne, Australia 5/Aug/04 4:17:40 PM
Aug 04 2004
next sibling parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <cesji2$14p4$1 digitaldaemon.com>, Derek Parnell says...

The docs say "virtual" functions only

I thought that /all/ member functions were virtual, unless explicitly marked as non-virtual by means of the keyword "final".
and you are not using it with virtual functions

I see no "final" - so I conclude that this is not so.
so call me silly.

No. I don't do that. Jill
Aug 05 2004
next sibling parent Derek <derek psyc.ward> writes:
On Thu, 5 Aug 2004 07:21:00 +0000 (UTC), Arcane Jill wrote:

 In article <cesji2$14p4$1 digitaldaemon.com>, Derek Parnell says...
 
The docs say "virtual" functions only

I thought that /all/ member functions were virtual, unless explicitly marked as non-virtual by means of the keyword "final".
and you are not using it with virtual functions

I see no "final" - so I conclude that this is not so.
so call me silly.

No. I don't do that. Jill

Oh! As I'm not used to the traditionally used OO jargon, I could probably do with a good OO Jargon Buster manual. I thought that a virtual function was one that didn't have a body, just a signature. abstract void Foo(); // virtual void Bar(){} // not virtual. I'll shut up now and go do some research on these terms ;-) -- Derek Melbourne, Australia
Aug 05 2004
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Arcane Jill wrote:

 In article <cesji2$14p4$1 digitaldaemon.com>, Derek Parnell says...
 
 The docs say "virtual" functions only

I thought that /all/ member functions were virtual, unless explicitly marked as non-virtual by means of the keyword "final".

From the docs: "All non-static non-private member functions are virtual." This is a private member being talked about, so there's a chance that it isn't virtual. Final doesn't declare a function to be non-virtual. In fact, a final method would need to be virtual if it is itself an override. From a semantic point of view, it's still virtual even if it isn't an override, but the compiler would no doubt optimise it to be non-virtual. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Aug 05 2004
next sibling parent reply Sean Kelly <sean f4.ca> writes:
In article <cetadn$1k9b$1 digitaldaemon.com>, Stewart Gordon says...
 From the docs:

"All non-static non-private member functions are virtual."

This is a private member being talked about, so there's a chance that it 
isn't virtual.

For the record, if you change the member to protected then it becomes virtual and prints "B." In fact it even prints "B" if override is removed. So I would consider this intended behavior. Sean
Aug 05 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Sean Kelly wrote:

 In article <cetadn$1k9b$1 digitaldaemon.com>, Stewart Gordon says...
 
From the docs:

"All non-static non-private member functions are virtual."

This is a private member being talked about, so there's a chance that it 
isn't virtual.

For the record, if you change the member to protected then it becomes virtual

Of course. Since A.test is private, it doesn't exist in the scope of B. And so B.test is a distinct method, with no relation to A.test. OTOH, if A.test is protected, then B inherits it. Consequently, a new B.test with the same parameters will override it.
 and prints "B."  In fact it even prints "B" if override is removed.  So I would
 consider this intended behavior.

I can't for the life of me see why the OP's code would ever print "B.". Intended behaviour AIUI is that override never has any effect on the code generated, only on compiler errors. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Aug 06 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <cevpin$75a$1 digitaldaemon.com>, Stewart Gordon says...
Of course.  Since A.test is private, it doesn't exist in the scope of B. 
   And so B.test is a distinct method, with no relation to A.test.

No, A.test /isn't/ private. Check back to the original bug report: class A { protected void create() { printf ("A"); } void test() { create(); } } class B : A { private override void create() { printf ("B"); } } void main() { B b = new B; b.test(); } As you will observe, A.create() is protected, and not final. Therefore, it is /reasonable/ to expect that a derived class may override it. In this case, a derived class B has overridden it, and, further, has made it private /at this point/ in order that it not be overridden further. I would therefore expect A.test() to call B.create(). No?
Aug 06 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Arcane Jill wrote:

 In article <cevpin$75a$1 digitaldaemon.com>, Stewart Gordon says...
 
Of course.  Since A.test is private, it doesn't exist in the scope of B. 
  And so B.test is a distinct method, with no relation to A.test.

No, A.test /isn't/ private. Check back to the original bug report:

Oops. <snip>
 As you will observe, A.create() is protected, and not final.   Therefore, it is
 /reasonable/ to expect that a derived class may override it.

Yes, but obviously not with a private method.
 In this case, a derived class B has overridden it, and, further, has made it
private /at this
 point/ in order that it not be overridden further.

I wouldn't have thought that you could tighten the access when overriding a method. You use final to stop it being overridden further, don't you?
 I would therefore expect A.test() to call B.create().

Is the actual effect of this (once the word override has been taken out) defined? It's certainly a cause of confusion, and I'm inclined to suggest it shouldn't be allowed. But that's one thing. The bug whereby non-overrides can be declared as override is another. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Aug 06 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <cf0h6b$ob2$1 digitaldaemon.com>, Stewart Gordon says...
 As you will observe, A.create() is protected, and not final.   Therefore, it is
 /reasonable/ to expect that a derived class may override it.

Yes, but obviously not with a private method.

Just to make things really interesting, I added another class. Note now that A's method is protected; B's method is private; and C's method is public: # class A # { # protected void create() # { # printf ("A"); # } # # void test() # { # create(); # } # } # # class B : A # { # private override void create() # { # printf ("B"); # } # } # # class C : B # { # override void create() # { # printf ("C"); # } # } # # void main() # { # B b = new B; # C c = new C; # b.test(); # c.test(); # } Compiles without complaint. Prints AC. Okay, so my understanding of "private" may not be correct, but this is not intuitive.
I wouldn't have thought that you could tighten the access when 
overriding a method.

A fair point. In which case, it should be a compile error to declare a private function with the same name and signature as a protected function in a base class - either with or without the keyword "override".
You use final to stop it being overridden further, 
don't you?

Yes of course. Silly me. Arcane Jill
Aug 06 2004
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Arcane Jill wrote:

 In article <cf0h6b$ob2$1 digitaldaemon.com>, Stewart Gordon says...
 
As you will observe, A.create() is protected, and not final.   Therefore, it is
/reasonable/ to expect that a derived class may override it.

Yes, but obviously not with a private method.

Just to make things really interesting, I added another class. Note now that A's method is protected; B's method is private; and C's method is public:

 Compiles without complaint.

Yes, because within a module everything is accessible. <snip>
 A fair point. In which case, it should be a compile error to declare a private
 function with the same name and signature as a protected function in a base
 class - either with or without the keyword "override".

I entirely agree. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Aug 09 2004
prev sibling parent Nick <Nick_member pathlink.com> writes:
In article <cetadn$1k9b$1 digitaldaemon.com>, Stewart Gordon says...
 From the docs:

"All non-static non-private member functions are virtual."

This is a private member being talked about, so there's a chance that it 
isn't virtual.

If it isn't virtual then the 'override' should not be allowed. However, it must be virtual, since it overrides a virtual function. That's how it works in C++ at least. And overriding a virtual member with a non-virtual one doesn't make much sense to me.
Final doesn't declare a function to be non-virtual.  In fact, a final 
method would need to be virtual if it is itself an override.  From a 
semantic point of view, it's still virtual even if it isn't an override, 
but the compiler would no doubt optimise it to be non-virtual.

I agree with this. Nick
Aug 05 2004
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Derek Parnell wrote:

<snip>
 I still think that there is no bug and it's your attempted usage that is
 the issue. The docs say "virtual" functions only and you are not using it
 with virtual functions - so call me silly.

That means that it's illegal to apply the override keyword to a non-virtual function. Not that doing so has no effect. So of course it's a bug. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Aug 05 2004