www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Sturcts with constructor (dmd1.x)

reply Nrgyzer <nrgyzer googlemail.com> writes:
Hello everyone,

I currently try to create a structure with a construtor, but I always get the
following messages:

Error: Foo.this constructors are only for class definitions
Error: constructor lisim.lsResult.lsResult.this special member functions not
allowed for structs

By compiling the follwing code:

struct Foo {
    int len;
    bool len_done;
    const char* str;
    int length()
    {   if (!len_done)
        {   len = strlen(str);
	    len_done = true;
        }
	return len;
    }
    this(char* str) { this.str = str; }
}
const Foo f = Foo("hello");
bar(f.length);

I found that source on
http://www.digitalmars.com/d/2.0/const-faq.html#logical-const. I know that this
source is for d2 and not for d1 but does d1 support similar operations (or is
there no support for struct-constructors)?

Thanks in advance :)
Jan 11 2010
next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Nrgyzer (nrgyzer googlemail.com)'s article
 Hello everyone,
 I currently try to create a structure with a construtor, but I always get the
following messages:
 Error: Foo.this constructors are only for class definitions
 Error: constructor lisim.lsResult.lsResult.this special member functions not
allowed for structs
 By compiling the follwing code:
 struct Foo {
     int len;
     bool len_done;
     const char* str;
     int length()
     {   if (!len_done)
         {   len = strlen(str);
 	    len_done = true;
         }
 	return len;
     }
     this(char* str) { this.str = str; }
 }
 const Foo f = Foo("hello");
 bar(f.length);
 I found that source on
http://www.digitalmars.com/d/2.0/const-faq.html#logical-const. I know that this source is for d2 and not for d1 but does d1 support similar operations (or is there no support for struct-constructors)?
 Thanks in advance :)
Struct constructors are D2 only. That said, you can fake them in D1 by overloading static opCall: struct Foo { uint field; static Foo opCall(SomeType someArgument) { Foo foo; // Do stuff. foo.field = someValue; return foo; } } auto foo = Foo(someArgument);
Jan 11 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
dsimcha:
 Struct constructors are D2 only.  That said, you can fake them in D1 by
 overloading static opCall:
Struct constructors are probably the D2 feature I miss more in D1 :-) Bye, bearophile
Jan 11 2010
parent reply grauzone <none example.net> writes:
bearophile wrote:
 dsimcha:
 Struct constructors are D2 only.  That said, you can fake them in D1 by
 overloading static opCall:
Struct constructors are probably the D2 feature I miss more in D1 :-)
Why?
 Bye,
 bearophile
Jan 11 2010
parent bearophile <bearophileHUGS lycos.com> writes:
grauzone:
 Struct constructors are probably the D2 feature I miss more in D1 :-)
Why?
During optimization phases I sometimes want to convert classes into structs, and then I want to allocate some of those struct instances on the heap and others on the stack. A struct constructor allows me to change as little as possible to the code that uses those new structs. Bye, bearophile
Jan 12 2010
prev sibling next sibling parent Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
On 01/11/2010 04:06 PM, Nrgyzer wrote:
 Hello everyone,

 I currently try to create a structure with a construtor, but I always get the
following messages:

 Error: Foo.this constructors are only for class definitions
 Error: constructor lisim.lsResult.lsResult.this special member functions not
allowed for structs

 By compiling the follwing code:

 struct Foo {
      int len;
      bool len_done;
      const char* str;
      int length()
      {   if (!len_done)
          {   len = strlen(str);
 	    len_done = true;
          }
 	return len;
      }
      this(char* str) { this.str = str; }
 }
 const Foo f = Foo("hello");
 bar(f.length);

 I found that source on
http://www.digitalmars.com/d/2.0/const-faq.html#logical-const. I know that this
source is for d2 and not for d1 but does d1 support similar operations (or is
there no support for struct-constructors)?

 Thanks in advance :)
get rid of the constructor and replace
 const Foo f = Foo("hello");
with const Foo f = Foo(0,false,"hello"); and it will work, if you can forgive how ugly it is.
Jan 11 2010
prev sibling next sibling parent reply Strtr <strtr spam.com> writes:
bearophile Wrote:

 grauzone:
 Struct constructors are probably the D2 feature I miss more in D1 :-)
Why?
During optimization phases I sometimes want to convert classes into structs, and then I want to allocate some of those struct instances on the heap and others on the stack. A struct constructor allows me to change as little as possible to the code that uses those new structs.
How much of an overhead is a call to a struct instance compared to a call to a object?
Jan 12 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Strtr:
 How much of an overhead is a call to a struct instance compared to a call to a
object?
The situation is more complex than that. Structs don't have a pointer to the virtual table and monitor, that saves memory and time. Less memory saves you time if you have to allocate a large number of structs, for cache effects. They can be allocated inside arrays (placement new allows you to do the same with objects too), and generally LDC seems able to inline and manage them more efficiently, it doesn't call a struct destructor. If you for example write a ray tracer in D and you compile it with the quite good LDC compiler, you can see a significant performance difference between using a struct to represent a 3D vector (3 doubles, 24 bytes, always stack-allocated) than using objects (even scoped objects, always allocated on the stack). In D there are structs for a purpose. D compilers aren't currently able to de-virtualize calls, so if you have a tree made with two kinds of nodes (internal ones and leaves) and you need to transverse it a very large number of times, you may end doing a large number of virtual calls (you have two versions of the walking methods). In this situation I've seen that using 3 tagged structs, one "virtual" little struct that gets never instantiated, plus the two different nodes, the LDC compiler is quite able to partially inline such recursive calls (it can be done with an iterative stack too, but the final performance is about the same and the code gets uglier), and the performance is visibly higher. Sometimes D structs allow you to optimize in ways that Python doesn't allow you to :-) (Java HotSpot is able to partially optimize this by itself, de-virtualizing and then partially inlining the virtual recursive calls. But D language is designed to not need such advanced compiler technology). Bye, bearophile
Jan 12 2010
parent Strtr <strtr spam.com> writes:
bearophile Wrote:

 Strtr:
 How much of an overhead is a call to a struct instance compared to a call to a
object?
The situation is more complex than that. Structs don't have a pointer to the virtual table and monitor, that saves memory and time. Less memory saves you time if you have to allocate a large number of structs, for cache effects. They can be allocated inside arrays (placement new allows you to do the same with objects too), and generally LDC seems able to inline and manage them more efficiently, it doesn't call a struct destructor. If you for example write a ray tracer in D and you compile it with the quite good LDC compiler, you can see a significant performance difference between using a struct to represent a 3D vector (3 doubles, 24 bytes, always stack-allocated) than using objects (even scoped objects, always allocated on the stack). In D there are structs for a purpose. D compilers aren't currently able to de-virtualize calls, so if you have a tree made with two kinds of nodes (internal ones and leaves) and you need to transverse it a very large number of times, you may end doing a large number of virtual calls (you have two versions of the walking methods). In this situation I've seen that using 3 tagged structs, one "virtual" little struct that gets never instantiated, plus the two different nodes, the LDC compiler is quite able to partially inline such recursive calls (it can be done with an iterative stack too, but the final performance is about the same and the code gets uglier), and the performance is visibly higher. Sometimes D structs allow you to optimize in ways that Python doesn't allow you to :-) (Java HotSpot is able to partially optimize this by itself, de-virtualizing and then partially inlining the virtual recursive calls. But D language is designed to not need such advanced compiler technology).
Thank you. I will read wikipedia about the virtual method table.
Jan 12 2010
prev sibling parent Nrgyzer <nrgyzer googlemail.com> writes:
dsimcha Wrote:

 == Quote from Nrgyzer (nrgyzer googlemail.com)'s article
 Hello everyone,
 I currently try to create a structure with a construtor, but I always get the
following messages:
 Error: Foo.this constructors are only for class definitions
 Error: constructor lisim.lsResult.lsResult.this special member functions not
allowed for structs
 By compiling the follwing code:
 struct Foo {
     int len;
     bool len_done;
     const char* str;
     int length()
     {   if (!len_done)
         {   len = strlen(str);
 	    len_done = true;
         }
 	return len;
     }
     this(char* str) { this.str = str; }
 }
 const Foo f = Foo("hello");
 bar(f.length);
 I found that source on
http://www.digitalmars.com/d/2.0/const-faq.html#logical-const. I know that this source is for d2 and not for d1 but does d1 support similar operations (or is there no support for struct-constructors)?
 Thanks in advance :)
Struct constructors are D2 only. That said, you can fake them in D1 by overloading static opCall: struct Foo { uint field; static Foo opCall(SomeType someArgument) { Foo foo; // Do stuff. foo.field = someValue; return foo; } } auto foo = Foo(someArgument);
Thanks - that solution works great :)
Jan 12 2010