www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 11754] New: Disallow changing the default parameters of overridden inherited functions

reply d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11754

           Summary: Disallow changing the default parameters of overridden
                    inherited functions
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc



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); } -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 16 2013
next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11754


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich gmail.com



08:50:51 PST ---
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
    {
    }
}
-----

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 19 2013
prev sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11754





 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?) -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 19 2013