www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why does this compile (method in class without return type)

reply nkm1 <t4nk074 openmailbox.org> writes:
Consider:

import std.stdio;

class A
{
     final print() { writeln(this); } // no return type
}

class B : A
{
     final void print() { writeln(this); }
}

void main()
{
     auto b = new B;
     b.print();

     A a1 = b;
     a1.print();

     A a2 = new A;
     a2.print();
}

That compiles:

$ dmd -de -w -g ./main.d
$ main
main.B
main.B
main.A

with dmd 2.074 on linux:

$ dmd --version
DMD64 D Compiler v2.074.0
Copyright (c) 1999-2017 by Digital Mars written by Walter Bright

Is that a bug? (in the compiler). I'm learning D, and I'm half 
way through Andrei's book; I also read the documentation (on D's 
website) and I think that shouldn't compile?
May 02
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2017-05-03 08:54, nkm1 wrote:
 Consider:

 import std.stdio;

 class A
 {
      final print() { writeln(this); } // no return type
 }

 class B : A
 {
      final void print() { writeln(this); }
 }

 void main()
 {
      auto b = new B;
      b.print();

      A a1 = b;
      a1.print();

      A a2 = new A;
      a2.print();
 }

 That compiles:

 $ dmd -de -w -g ./main.d
 $ main
 main.B
 main.B
 main.A

 with dmd 2.074 on linux:

 $ dmd --version
 DMD64 D Compiler v2.074.0
 Copyright (c) 1999-2017 by Digital Mars written by Walter Bright

 Is that a bug? (in the compiler). I'm learning D, and I'm half way
 through Andrei's book; I also read the documentation (on D's website)
 and I think that shouldn't compile?
It might be by accident but I think the compiler is inferring the return type. Just as "auto" is not necessary to infer the type of a variable if there's another attribute: auto a = 3; const auto b = 4; // here "auto" is redundant const c = 5; In your case you have "final" as the attribute. -- /Jacob Carlborg
May 03
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, 3 May 2017 at 07:37:31 UTC, Jacob Carlborg wrote:
 It might be by accident but I think the compiler is inferring 
 the return type. Just as "auto" is not necessary to infer the 
 type of a variable if there's another attribute:

 auto a = 3;
 const auto b = 4; // here "auto" is redundant
 const c = 5;

 In your case you have "final" as the attribute.
Yes, the compiler is inferring the return type. However, it _should_ be inferring it as void, and the override in B should then be illegal. If I stick pragma(msg, typeof(print)); right after each declaration for print, then it prints system void() for A and void() for B, which is odd, since both should be system. Interestingly, if both have pragmas at the same time, _then_ I get a compilation error: qd.d(11): Error: function qd.B.print cannot override final function qd.A.print So, I'd say that there's definitely a bug here.
May 03
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, 3 May 2017 at 08:10:04 UTC, Jonathan M Davis wrote:
 So, I'd say that there's definitely a bug here.
https://issues.dlang.org/show_bug.cgi?id=17366
May 03
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 3 May 2017 at 07:37:31 UTC, Jacob Carlborg wrote:
 It might be by accident but I think the compiler is inferring 
 the return type. Just as "auto" is not necessary to infer the 
 type of a variable if there's another attribute:
No accident there, the spec says any storage class will do: http://dlang.org/spec/function.html#auto-functions "An auto function is declared without a return type. If it does not already have a storage class, use the auto storage class. "
May 03
parent Jacob Carlborg <doob me.com> writes:
On 2017-05-03 14:50, Adam D. Ruppe wrote:

 No accident there, the spec says any storage class will do:
 http://dlang.org/spec/function.html#auto-functions

 "An auto function is declared without a return type. If it does not
 already have a storage class, use the auto storage class. "
I see. -- /Jacob Carlborg
May 08
prev sibling next sibling parent nkm1 <t4nk074 openmailbox.org> writes:
On Wednesday, 3 May 2017 at 06:54:15 UTC, nkm1 wrote:
 final method type inference stuff
Jacob and Jonathan - thank you, this is clear to me now. Hopefully it will get fixed at some point.
May 03
prev sibling parent reply Daniel =?UTF-8?B?S296w6Fr?= via Digitalmars-d-learn writes:
V Wed, 03 May 2017 06:54:15 +0000
nkm1 via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
napsáno:

 Consider:
 
 import std.stdio;
 
 class A
 {
      final print() { writeln(this); } // no return type
 }
 
 class B : A
 {
      final void print() { writeln(this); }
 }
 
 void main()
 {
      auto b = new B;
      b.print();
 
      A a1 = b;
      a1.print();
 
      A a2 = new A;
      a2.print();
 }
 
 That compiles:
 
 $ dmd -de -w -g ./main.d
 $ main
 main.B
 main.B
 main.A
 
 with dmd 2.074 on linux:
 
 $ dmd --version
 DMD64 D Compiler v2.074.0
 Copyright (c) 1999-2017 by Digital Mars written by Walter Bright
 
 Is that a bug? (in the compiler). I'm learning D, and I'm half 
 way through Andrei's book; I also read the documentation (on D's 
 website) and I think that shouldn't compile?
print in A is template: import std.stdio; class A { template print() { void print() { writeln("A version"); } // no return type } } class B : A { final void print() { writeln("B version"); } } void main() { auto b = new B; b.print(); A a1 = b; a1.print(); A a2 = new A; a2.print(); } // output: B version A version A version
May 03
next sibling parent reply nkm1 <t4nk074 openmailbox.org> writes:
On Wednesday, 3 May 2017 at 07:34:03 UTC, Daniel Kozák wrote:
 print in A is template:
What :) How does it interact with 'final'?
May 03
next sibling parent Daniel =?UTF-8?B?S296w6Fr?= via Digitalmars-d-learn writes:
V Wed, 03 May 2017 09:21:47 +0000
nkm1 via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
napsáno:

 On Wednesday, 3 May 2017 at 07:34:03 UTC, Daniel Kozák wrote:
 print in A is template:
  
What :) How does it interact with 'final'?
final is not important here
May 03
prev sibling next sibling parent Daniel =?UTF-8?B?S296w6Fr?= via Digitalmars-d-learn writes:
V Wed, 03 May 2017 09:21:47 +0000
nkm1 via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
napsáno:

 On Wednesday, 3 May 2017 at 07:34:03 UTC, Daniel Kozák wrote:
 print in A is template:
  
What :) How does it interact with 'final'?
hmm obviously it is problem only with final
May 03
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, 3 May 2017 at 09:21:47 UTC, nkm1 wrote:
 On Wednesday, 3 May 2017 at 07:34:03 UTC, Daniel Kozák wrote:
 print in A is template:
What :) How does it interact with 'final'?
If it were a template (and it's not), then final would not be applicable, because templated functions cannot be virtual. - Jonathan M Davis
May 03
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, 3 May 2017 at 07:34:03 UTC, Daniel Kozák wrote:
 V Wed, 03 May 2017 06:54:15 +0000
 nkm1 via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
 napsáno:

 Consider:
 
 import std.stdio;
 
 class A
 {
      final print() { writeln(this); } // no return type
 }
 
 class B : A
 {
      final void print() { writeln(this); }
 }
 
 void main()
 {
      auto b = new B;
      b.print();
 
      A a1 = b;
      a1.print();
 
      A a2 = new A;
      a2.print();
 }
 
 That compiles:
 
 $ dmd -de -w -g ./main.d
 $ main
 main.B
 main.B
 main.A
 
 with dmd 2.074 on linux:
 
 $ dmd --version
 DMD64 D Compiler v2.074.0
 Copyright (c) 1999-2017 by Digital Mars written by Walter 
 Bright
 
 Is that a bug? (in the compiler). I'm learning D, and I'm half 
 way through Andrei's book; I also read the documentation (on 
 D's website) and I think that shouldn't compile?
print in A is template: import std.stdio; class A { template print() { void print() { writeln("A version"); } // no return type } }
How is it a template in the original example? final print() { writeln(this); } // no return type does not have the extra set of parens required to turn it into a template. It _does_ use inference, just like static a = 42; uses inference and final auto print() { writeln(this); } uses inference, but it shouldn't be a template any more than static a = 42; is a template. - Jonathan M Davis
May 03