Jump to page: 1 2
Thread overview
[Issue 4247] New: Cannot create default-constructed struct on heap when constructor is defined
Sep 11, 2010
Andrej Mitrovic
Sep 11, 2010
nfxjfg@gmail.com
Sep 11, 2010
Andrej Mitrovic
Sep 11, 2010
Andrej Mitrovic
Feb 18, 2013
Andrej Mitrovic
Apr 15, 2013
Maksim Zholudev
Apr 16, 2013
Kenji Hara
May 28, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4247

           Summary: Cannot create default-constructed struct on heap when
                    constructor is defined
           Product: D
           Version: 2.041
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: major
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: schveiguy@yahoo.com


--- Comment #0 from Steven Schveighoffer <schveiguy@yahoo.com> 2010-05-28 15:55:49 PDT ---
If I want a struct on the heap, I do this:

struct S
{
}

auto s = new S;

But if I give S a constructor:

struct S
{
  this(int n) {}
}

auto s = new S;

dmd complains:
Error: constructor S.this (int n) is not callable using argument types ()

So I do this:

struct S
{
  this() {}
  this(int n) {}
}

but dmd now complains:
Error: constructor S.this default constructor not allowed for structs

So the auto s = new S is no longer usable.  However, I can easily declare a struct S on the stack, or create a new array of S.  In fact, you can do:

auto s = (new S[1])[0];

and achieve the desired effect, but this is oh so ugly.

Bottom line, if I can construct a struct on the stack, I should be able to identically construct it on the heap.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 11, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4247


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

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


--- Comment #1 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2010-09-11 06:37:01 PDT ---
You can't make your own default constructor for structs, this is explained in TDPL. A constructor with no arguments is created by default, with each field of a struct initialized to it's type's .init property. You cannot override this. See page 244 in TDPL.

Also, since when are structs allowed to be allocated on the heap? TDPL explicitly states that structs have scoped lifetime.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 11, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4247


bearophile_hugs@eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs@eml.cc


--- Comment #2 from bearophile_hugs@eml.cc 2010-09-11 07:00:37 PDT ---
(In reply to comment #1)
> Also, since when are structs allowed to be allocated on the heap? TDPL explicitly states that structs have scoped lifetime.

I double TDPL says this. And if it says so, then it's wrong. TDPL is not a religious book.


> You cannot override this. See page 244 in TDPL.

The reason given at page 244 is that all type needs a statically defined init.

On the other hand the need to allocate a struct on the heap with no arguments is real, and the current workarounds look bad for a nice language as D2. This small program shows that you can create a S2 on the stack:


struct S1 {}
struct S2 {
    this(int) {}
}
void main() {
    S1 s1a;
    auto s1b = new S1;
    S2 s2a; // OK
    auto s2b = new S2; // ERR
}


So I think "new S2;" may just create the same struct that "S2 s2a;" creates, but allocate it on the heap instead of the stack. I think this is a solution.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 11, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4247


nfxjfg@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |nfxjfg@gmail.com


--- Comment #3 from nfxjfg@gmail.com 2010-09-11 07:10:59 PDT ---
(In reply to comment #1)
> Also, since when are structs allowed to be allocated on the heap? TDPL explicitly states that structs have scoped lifetime.

If structs couldn't be allocated on the heap, you'd have to forget about struct arrays. And this is pure bullshit. E.g. this wouldn't be allowed anymore:

S[] array;
array.length = 1;

You couldn't seriously want this to be illegal.

(This code snippet also shows that it's advantageous to force structs having a "simple" default ctor, i.e. one that doesn't require the runtime to run code on each element to construct it.)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 11, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4247



--- Comment #4 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2010-09-11 08:00:51 PDT ---
(In reply to comment #2)
> (In reply to comment #1)
> > Also, since when are structs allowed to be allocated on the heap? TDPL explicitly states that structs have scoped lifetime.
> 
> I double TDPL says this. And if it says so, then it's wrong. TDPL is not a religious book.
> 

It's not a religious book, but since the D docs aren't kept up to date, who can you trust? And AFAIK Andrei & Walter have both reviewed TDPL and agree with what it states there. As for structs on the heap, I simply didn't know it was possible to do that, so maybe I judged to quickly from what I've read.

Whether it's legal or not is not up to me, so don't take it personal please. :)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 11, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4247


Andrei Alexandrescu <andrei@metalanguage.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrei@metalanguage.com


--- Comment #5 from Andrei Alexandrescu <andrei@metalanguage.com> 2010-09-11 09:57:21 PDT ---
(In reply to comment #4)
> (In reply to comment #2)
> > (In reply to comment #1)
> > > Also, since when are structs allowed to be allocated on the heap? TDPL explicitly states that structs have scoped lifetime.
> > 
> > I double TDPL says this. And if it says so, then it's wrong. TDPL is not a religious book.
> > 
> 
> It's not a religious book, but since the D docs aren't kept up to date, who can you trust? And AFAIK Andrei & Walter have both reviewed TDPL and agree with what it states there. As for structs on the heap, I simply didn't know it was possible to do that, so maybe I judged to quickly from what I've read.
> 
> Whether it's legal or not is not up to me, so don't take it personal please. :)

Obviously there are many ways to allocate struct objects on the heap: using new, as members of class objects, or as elements of arrays. All of them are described in TDPL. If some particular sentence of TDPL seems to rule out such possibilities please let me know.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 11, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4247



--- Comment #6 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2010-09-11 10:45:49 PDT ---
(In reply to comment #5)
> (In reply to comment #4)
> > (In reply to comment #2)
> > > (In reply to comment #1)
> > > > Also, since when are structs allowed to be allocated on the heap? TDPL explicitly states that structs have scoped lifetime.
> > > 
> > > I double TDPL says this. And if it says so, then it's wrong. TDPL is not a religious book.
> > > 
> > 
> > It's not a religious book, but since the D docs aren't kept up to date, who can you trust? And AFAIK Andrei & Walter have both reviewed TDPL and agree with what it states there. As for structs on the heap, I simply didn't know it was possible to do that, so maybe I judged to quickly from what I've read.
> > 
> > Whether it's legal or not is not up to me, so don't take it personal please. :)
> 
> Obviously there are many ways to allocate struct objects on the heap: using new, as members of class objects, or as elements of arrays. All of them are described in TDPL. If some particular sentence of TDPL seems to rule out such possibilities please let me know.

Described where exactly? I haven't seen any snippet of code using new for struct objects in the structs section from page 240 onwards. There's a mention of using classes inside structs, and dynamic arrays inside structs (where the postblit constructor comes in handy), but no mention on how to use structs on the heap. Maybe it's in a different section..?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 18, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=4247



--- Comment #7 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-02-18 10:05:18 PST ---
(In reply to comment #6)
> Described where exactly?

Please ignore my comments from before as I didn't know at the time 'new'ing was possible for structs.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 15, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=4247


Maksim Zholudev <maximzms@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |maximzms@gmail.com


--- Comment #8 from Maksim Zholudev <maximzms@gmail.com> 2013-04-15 07:09:04 PDT ---
(In reply to comment #0)
> So the auto s = new S is no longer usable.  However, I can easily declare a struct S on the stack, or create a new array of S.  In fact, you can do:
> 
> auto s = (new S[1])[0];
> 
> and achieve the desired effect, but this is oh so ugly.

This code would create structure on the heap and put COPY of it to `s`. It is not the same as `auto s = new S`.

The workaround should be:
--------------------
auto s = (new S[1]).ptr;
--------------------

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 15, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=4247



--- Comment #9 from Steven Schveighoffer <schveiguy@yahoo.com> 2013-04-15 10:26:37 PDT ---
(In reply to comment #8)
> (In reply to comment #0)
> > So the auto s = new S is no longer usable.  However, I can easily declare a struct S on the stack, or create a new array of S.  In fact, you can do:
> > 
> > auto s = (new S[1])[0];
> > 
> > and achieve the desired effect, but this is oh so ugly.
> 
> This code would create structure on the heap and put COPY of it to `s`. It is not the same as `auto s = new S`.
> 
> The workaround should be:
> --------------------
> auto s = (new S[1]).ptr;
> --------------------

Oh yes!  I was missing an & :)

Thanks

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2