On Tuesday, 27 October 2015 at 22:23:15 UTC, bitwise wrote:
[...]
I just did a test for this. Using dmd's -H flag to generate header files, the bodies of member functions are removed. If you link a static library containing the compiled class though, everything will work, and you can still inherit the class.

[test.d]
module test;
import std.stdio;
class Test { void foo() { writeln("test"); } }
[/test.d]

[main.d]
module main;
import test;
import std.stdio;
class Derived : Test {
    override void foo() { writeln("derived"); }
}
void main() {
    Derived d = new Derived();
    d.foo(); // prints "derived"
}
[/main.d]

With the above two files, I did this:

dmd test.d -lib -H
rm test.d   #make sure dmd can't find body of foo()
dmd main.d test.a
./main

The above will print "derived".

I think dmd -H should definitely keep the definitions of auto override functions when generating headers, but in theory,

-H also keeps the body of template functions so I would assume it would treat auto overrides the same.

someone could remove them, and things could still work. If someone received a static library and a D header file with missing auto override function, they wouldn't be able to inherit from the class, as if it were a sealed/final class. This person, however, could work around the problem by overriding the missing auto override function. I suppose this is a good reason to adopt the semantics you are recommending, where overriding an auto override function stops the automatic behaviour, or else someone would have to override missing auto override functions for every single level of inheritance after the missing auto override. I suppose that if someone wanted to resume the auto overrides, they could just override with another auto override, and call the base class implementation from their new override. With regards to the resuming of auto overriding though, I'm wondering if what I am proposing is possible in D. In C++, you can call any base method from anywhere in a class hierarchy. In D however, it doesn't seem to work.

I think you are correct, there is a scenario where one might want to provide a header to a class and not include the auto override body. An alternative solution could be that if you provide a header to a class and don't include the auto override body, then the auto override functionality is removed and the method is treated as a regular method from that point on(with the most recent version of the method being the one that is used). This would allow the class to still be inherited later on.

[C++ ]
struct A { virtual void foo() { printf("A\n"); } };
struct B : public A { void foo() { printf("B\n"); } };
struct C : public B { void foo() { A::foo(); } };
int main() {
        C c;
        c.foo();   // prints "A"
}
[/C++]

In D however, the following will cause a compiler error:
"Error: identifier expected following '.', not 'super'"

[D]
class A { void foo() { writeln("A"); } }
class B : A { override void foo() { writeln("B"); } }
class C : B { override void foo() { super.super.foo(); } }
void main() {
    C c = new C();
    c.foo();
}
[/D]

    Bit

A.foo() or B.foo() seems to work instead of super.super.foo() or super.foo()

Reply via email to