www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - WTF abstract is?

reply "Zhouxuan" <pycerl qq.com> writes:
////////////////////////////////////////////////////////////
//case 1

class A
{
     abstract void foo();
}

class B : A
{
     static if( __traits(isAbstractClass, typeof(this) ))
     {
     }

     override void foo()
     {
     }
}

void main()
{
     B b = new B();
}

//Error: cannot create instance of abstract class B
////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////
//case 2

abstract class A
{
     void foo();
}

class B : A
{
     static if( __traits(isAbstractClass, typeof(this) ))
     {
     }

     override void foo()
     {
     }
}

void main()
{
     B b = new B();
}

//Okay
////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////
//case 3

class A
{
     abstract void foo();
}

class B : A
{
     override void foo()
     {
     }
}

void main()
{
     B b = new B();
}

//Okay
////////////////////////////////////////////////////////////

How awkward it is given that "D is as old as C#"!

Do you guys never used abstract class?
Oct 03 2013
next sibling parent "Zhouxuan" <pycerl qq.com> writes:
bug again!
http://forum.dlang.org/thread/rufoxrnrvlyqdsvnyfjf forum.dlang.org
Oct 03 2013
prev sibling next sibling parent "Zhouxuan" <pycerl qq.com> writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11169
http://d.puremagic.com/issues/show_bug.cgi?id=11170
Oct 03 2013
prev sibling next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Friday, 4 October 2013 at 05:07:53 UTC, Zhouxuan wrote:
 ////////////////////////////////////////////////////////////
 //case 1

 class A
 {
     abstract void foo();
 }

 class B : A
 {
     static if( __traits(isAbstractClass, typeof(this) ))

this is invalid here. Not sure what you try to achieve via this static if.
     {
     }

     override void foo()
     {
     }
 }

 void main()
 {
     B b = new B();
 }

 //Error: cannot create instance of abstract class B

That is a bug.
 ////////////////////////////////////////////////////////////

 ////////////////////////////////////////////////////////////
 //case 2

 abstract class A
 {
     void foo();
 }

 class B : A
 {
     static if( __traits(isAbstractClass, typeof(this) ))
     {
     }

     override void foo()
     {
     }
 }

 void main()
 {
     B b = new B();
 }

 //Okay

It shouldn't, A.foo is not defined. You should get a link error.
 ////////////////////////////////////////////////////////////

 ////////////////////////////////////////////////////////////
 //case 3

 class A
 {
     abstract void foo();
 }

 class B : A
 {
     override void foo()
     {
     }
 }

 void main()
 {
     B b = new B();
 }

 //Okay

This one work as expected :D
 ////////////////////////////////////////////////////////////

 How awkward it is given that "D is as old as C#"!

 Do you guys never used abstract class?

Not that much. Note that error comes up when abstract is mixed with static if and compile time reflection, both are not present in C#.
Oct 03 2013
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 10/03/2013 11:10 PM, deadalnix wrote:

 On Friday, 4 October 2013 at 05:07:53 UTC, Zhouxuan wrote:
 ////////////////////////////////////////////////////////////
 //case 1

 class A
 {
     abstract void foo();
 }

 class B : A
 {
     static if( __traits(isAbstractClass, typeof(this) ))

this is invalid here. Not sure what you try to achieve via this

Well, obviously that is the reason for the bug. :) I think Zhouxuan thinks that it is an 'abstract' bug but actually it is some sort of __traits caching issue. It would indeed be weird for isAbstractClass to delay its value until the whole class definition is seen. Instead, what seems to happen is that isAbstractClass caches the first value that it determines and perhaps at least for consistency uses that value. Moving isAbstractClass after the definition of B.foo removes the issue in this case: class A { abstract void foo(); } class B : A { override void foo() { } // Added by Ali: pragma(msg, __traits(isAbstractClass, typeof(this))); static if( __traits(isAbstractClass, typeof(this) )) { } } void main() { B b = new B(); // now compiles } Ali
Oct 03 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 10/04/2013 08:22 AM, Ali Çehreli wrote:
  >>
  >> class B : A
  >> {
  >>     static if( __traits(isAbstractClass, typeof(this) ))
  >
  > this is invalid here. Not sure what you try to achieve via this
 static if.

 Well, obviously that is the reason for the bug. :) I think Zhouxuan
 thinks that it is an 'abstract' bug but actually it is some sort of
 __traits caching issue.

 It would indeed be weird for isAbstractClass to delay its value until
 the whole class definition is seen.
 ...

It has to delay it's value until it has seen as much as possible without knowing it. Then eg. emit a compile time error if the body of the static if actually changes the determined fact. (Or use some sound relaxation of that rule.) Many compile-time reflection features can be used to provoke this kind of issue. (E.g. write a class that subclasses another class iff it cannot access some protected field of it.)
Nov 07 2013
prev sibling next sibling parent "Zhouxuan" <pycerl qq.com> writes:
On Friday, 4 October 2013 at 06:10:30 UTC, deadalnix wrote:
 On Friday, 4 October 2013 at 05:07:53 UTC, Zhouxuan wrote:
 ////////////////////////////////////////////////////////////
 //case 1

 class A
 {
    abstract void foo();
 }

 class B : A
 {
    static if( __traits(isAbstractClass, typeof(this) ))

this is invalid here. Not sure what you try to achieve via this static if.

I want to define some variables in non-abstract class.
Oct 03 2013
prev sibling parent "Zhouxuan" <pycerl qq.com> writes:
On Friday, 4 October 2013 at 06:22:57 UTC, Ali Çehreli wrote:
 On 10/03/2013 11:10 PM, deadalnix wrote:

 On Friday, 4 October 2013 at 05:07:53 UTC, Zhouxuan wrote:
 ////////////////////////////////////////////////////////////
 //case 1

 class A
 {
     abstract void foo();
 }

 class B : A
 {
     static if( __traits(isAbstractClass, typeof(this) ))

this is invalid here. Not sure what you try to achieve via

Well, obviously that is the reason for the bug. :) I think Zhouxuan thinks that it is an 'abstract' bug but actually it is some sort of __traits caching issue. It would indeed be weird for isAbstractClass to delay its value until the whole class definition is seen. Instead, what seems to happen is that isAbstractClass caches the first value that it determines and perhaps at least for consistency uses that value. Moving isAbstractClass after the definition of B.foo removes the issue in this case:

Indeed I found the issue from use of isAbstractClass, but after some tests I'm confused by these abstract use cases.
Oct 03 2013