D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5420 - Cannot override function error
Summary: Cannot override function error
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All Windows
: P2 normal
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-01-06 18:35 UTC by eatingstaples
Modified: 2012-01-20 16:20 UTC (History)
3 users (show)

See Also:


Attachments
Code demonstrating various working and non-working overrides (543 bytes, application/octet-stream)
2011-01-06 18:36 UTC, eatingstaples
Details
Code attached with the problem fixed. (533 bytes, application/octet-stream)
2011-01-06 19:51 UTC, eatingstaples
Details

Note You need to log in before you can comment on or make changes to this issue.
Description eatingstaples 2011-01-06 18:35:48 UTC
Derived classes cannot override functions in base classes, if the base class is private or package, even if the derived class carries the same attribute.

The compiler issues an error explaining that the function in the derived class does not, in fact, override a function in the base class.
Comment 1 eatingstaples 2011-01-06 18:36:58 UTC
Created attachment 862 [details]
Code demonstrating various working and non-working overrides
Comment 2 Jonathan M Davis 2011-01-06 18:55:12 UTC
As it stands, I don't believe that this is actually an error. All private functions are non-virtual, and package functions probably are as well. protected and and public functions _are_ virtual and so can be overridden. It _is_ true that in C++ you can override private functions, but there is some debate as to whether you should be allowed to in D. TDPL claims that you can, which would imply that dmd will have to be changed to make it possible to make private and package functions virtual (which could actually harm efficiency a fair bit due to the inability to inline), but there have been definite arguments against it, since you can essentially use protected in any case where you'd use private. See bug# 4542.

This is one of those cases where it's not clear whether dmd is going to end up matching TDPL or whether TDPL will have to be changed in future editions. I don't believe that Walter has said anything about what he intends to do on the matter. There have been discussions about this on the newsgroup before.

Personally, I'm rather divided. NVI is definitely useful, but you can pretty much do it with protected, and it's not clear that private actually buys you much over using protected. And given that making private virtual would seriously harm inlining, that would tend to indicate that perhaps TDPL should be changed rather than dmd. I don't know though, and until Walter decides and tells us what he decided, we won't know. You might wan to go search the archives for discussions on the issue though.
Comment 3 eatingstaples 2011-01-06 19:37:13 UTC
I understand that, but I didn't realize it applied even to public functions in private classes. That seems nonsensical, as there may be entire hierarchies hidden inside a package which can then not use any virtual functions.
Comment 4 eatingstaples 2011-01-06 19:50:40 UTC
Looking over the D2 language documentation, I still see no reason that this should be occurring;
"All non-static non-private non-template member functions are virtual."

and 

"Private means that only members of the enclosing class can access the member, or members and functions in the same module as the enclosing class. Private members cannot be overridden. Private module members are equivalent to static declarations in C programs.

Package extends private so that package members can be accessed from code in other modules that are in the same package. This applies to the innermost package only, if a module is in nested packages. "

Nowhere can I find that it says declaring a class private or package causes its members to be considered the same.
Comment 5 eatingstaples 2011-01-06 19:51:37 UTC
Created attachment 863 [details]
Code attached with the problem fixed.
Comment 6 eatingstaples 2011-01-06 19:52:46 UTC
Comment on attachment 863 [details]
Code attached with the problem fixed.

Explicitly declaring the members public fixes the problem. However, members are public by default, so this appears to be a bug.
Comment 7 Jonathan M Davis 2011-01-06 20:03:47 UTC
Hmmmm. Well, I believe that members are public by default because public is the default access level of the class. If you mark the class as private, that would mark _all_ of its functions as private, just like marking a class as immutable makes all of its functions immutable. So, that's not a bug. A bit annoying perhaps, but not a bug.
Comment 8 Christopher Nicholson-Sauls 2011-01-06 21:15:51 UTC
Like Jon said, this is consistent with how other decorations on classes are treated: they propagate to members.  Declare a class as const, immutable, or even shared (!?), and all members are treated likewise.  If nothing else, you can always get in the habit of adding 'public:' at the beginning of such classes.  (Plenty of people do that already, out of C++ habit.)  I'm definitely not saying it isn't going to be annoying, but I think it fits the language (as is).
Comment 9 Walter Bright 2012-01-20 16:20:51 UTC
The original example compiles without error on 2.057.