Bug 11754 – Disallow changing the default parameters of overridden inherited functions
Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-12-16T14:58:11Z
Last change time
2020-08-04T04:21:06Z
Assigned to
No Owner
Creator
bearophile_hugs
Comments
Comment #0 by bearophile_hugs — 2013-12-16T14:58:11Z
Perhaps it's a good idea to statically disallow code like this (returning a compilation error), that changes the default parameters of overridden inherited functions:
import std.stdio;
class Base {
/*virtual*/ void foo(int i = 10) {
writeln("Base.foo() ", i);
}
}
class Derived: Base {
override /*virtual*/ void foo(int i = 20) { // line 8
writeln("Derived.foo() ", i);
}
}
void main() {
Base c1 = new Base;
c1.foo(); // Output: Base.foo() 10
Derived c2 = new Derived;
c2.foo(); // Output: Derived.foo() 20
Base c3 = new Derived;
c3.foo(); // Output: Derived.foo() 10
}
The explanation:
http://www.gotw.ca/gotw/005.htm
> Like overloads, default parameters are taken from the static type (here Base) of the object,
> hence the default value of 10 is taken. However, the function happens to be virtual,
> and so the function actually called is based on the dynamic type (here Derived) of the object.
So I suggest that D code to give an error message like:
test.d(8): Error: changing default arguments of overridden inherited functions is not allowed
Code like this is OK:
void foo(int i) {
...
override void foo(int i) {
Just as:
void foo(int i = 10) {
...
override void foo(int i = 10) {
------------------
Alternative design: just give a warning instead of an error.
------------------
Alternative design: the error message could be shown only if there is one actual function call that doesn't specify the missing argument. This means in this alternative design this main() doesn't generate the error message:
void main() {
Base c1 = new Base;
c1.foo(10);
Derived c2 = new Derived;
c2.foo(10);
Base c3 = new Derived;
c3.foo(10);
}
Comment #1 by andrej.mitrovich — 2013-12-19T08:50:51Z
What if the initializer in the base class is private?
-----
module a;
private int priv;
class A
{
void foo(int x = priv) { }
}
-----
-----
module b;
import a;
class B : A
{
override void foo(int x = priv) // error: "priv" is private
{
}
}
-----
Comment #2 by bearophile_hugs — 2013-12-19T14:14:46Z
(In reply to comment #1)
> What if the initializer in the base class is private?
After the restriction that I have suggested to add, you can't write that code. You have to solve the problem in some other way. (Perhaps using an overloaded method?)
Comment #3 by pro.mathias.lang — 2020-08-04T04:21:06Z
That seems like a pointless restriction. Closing as WONTFIX.