Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A private class member functions should not be final implicitly #20818

Open
Bolpat opened this issue Feb 4, 2025 · 6 comments
Open

A private class member functions should not be final implicitly #20818

Bolpat opened this issue Feb 4, 2025 · 6 comments

Comments

@Bolpat
Copy link
Contributor

Bolpat commented Feb 4, 2025

Pattern that this rule makes impossible:

class Base
{
    private void f() { }
}

class Derived : Base
{
    override void f() { } // error: function `void D.f()` does not override any function, did you mean to override `void C.f()`?
}

In D, private restricts visibility to the module, not the class. Accessing a private member of a class outside of it is trivial and meaningful. This is something that should “obviously work” as soon as one understands what private means in D. The rule that private implies final probably stems from C++ and Java, where private restricts visibility to the class. A private member function can be made final by the optimizer if it is determined that it’s not actually overridden.

A workaround is to put the module in its own package and make the members package.

@mdparker
Copy link
Member

mdparker commented Feb 5, 2025

It would break the contract of private to allow overrides. The workaround is to use protected. That's what it's for.

@12345swordy
Copy link
Contributor

It doesn't make any sense for private to be override just because its in the same module.

@Bolpat
Copy link
Contributor Author

Bolpat commented Feb 5, 2025

private applies to the whole module. You’re all talking Java.

@mdparker
Copy link
Member

mdparker commented Feb 5, 2025

Yes, private applies to the module. So what about a subclass outside of the module? Would you argue that the overridden function should then be private to the subclass's module? That seems incredibly unintuitive, as it's then not really private-to-the-module. Or would you argue that overriding outside of the module should be an error? That makes more sense, but it's still a massively breaking change for very little gain.

@Bolpat
Copy link
Contributor Author

Bolpat commented Feb 5, 2025

Or would you argue that overriding outside of the module should be an error?

Yes, you can’t override what you can’t see. Outside the module, it’s not visible, ergo you can’t override it. To me, that was completely obvious.

That makes more sense, but it's still a massively breaking change for very little gain.

Is it a breaking change? IIUC, it does affect the ABI because the vtable changes, but it could be done in a new edition. I don’t know if it’s that big of a deal since altering package member functions is also an ABI change even though the affected stuff isn’t visible outside the package (which I guess is where ABI changes are relevant).

The workaround is to use protected.

A protected member is essentially public, which is the opposite. (The name is very misleading.) The workaround is to use package, which needlessly over-extends the visibility unless one puts the module in its own package.

@12345swordy
Copy link
Contributor

12345swordy commented Feb 5, 2025

No, a protected member, isn't essentially public, as you can't access it outside the class outside the module, while with public you certainly can. Protected and public is not the same thing!

A better solution is to allow writing this:

private protected int x() {}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants