Bug 1860 – Heap construction of structs with args doesn't work

Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Windows
Creation time
2008-02-21T15:28:48Z
Last change time
2020-02-08T09:57:33Z
Assigned to
Walter Bright
Creator
Bill Baxter

Comments

Comment #0 by wbaxter — 2008-02-21T15:28:48Z
Heap construction of structs using arguments doesn't work. It doesn't matter if there's a static opCall explicitly defined or not. ----- struct NoOpCalls { int i; float x; } struct WithOpCall { static WithOpCall opCall(int _i, float _x) { WithOpCall R; with(R) { i = _i; x = _x; } return R; } int i; float x; } void main() { auto stacka = NoOpCalls(2, 5.0); // ok auto stackb = WithOpCall(2, 5.0); // ok auto heapa = new NoOpCalls(2, 5.0); // error no constructor auto heapb = new WithOpCall(2, 5.0); // error no constructor } ---- This seems like an oversight rather than a deliberate design decision. You can work around by "double initializing": auto heapa = new NoOpCalls; *heapa = NoOpCalls(2,5.0); But that seems unnecessarily repetitive. Anyway, this is yet another reason why structs should have real constructors, as opposed to the static opCall hack.
Comment #1 by default_357-line — 2008-02-22T00:45:28Z
Try this. import std.gc struct heapmalloc(T) { static T* opCall(U...)(U u) { auto res = cast(T*) malloc(T.sizeof); (*res) = T(u); return res; } } struct Foo { int a; float b; } void main() { auto heapfoo = heapmalloc!(Foo)(1984, 3.14159); }
Comment #2 by default_357-line — 2008-02-22T00:45:32Z
downs wrote: > Try this. > > import std.gc; > struct heapmalloc(T) { > static T* opCall(U...)(U u) { > auto res = cast(T*) malloc(T.sizeof); > (*res) = T(u); > return res; > } > } > > > struct Foo { > int a; > float b; > } > > void main() { > auto heapfoo = heapmalloc!(Foo)(1984, 3.14159); > } Or this. import std.gc; T* toHeap(T)(T st) { auto res = cast(T*) malloc(T.sizeof); (*res) = st; return res; } struct Foo { int a; float b; } void main() { auto th = toHeap(Foo(1984, 3.1415926)); assert(th.a == 1984); } :) --downs
Comment #3 by default_357-line — 2008-02-22T00:50:23Z
downs wrote: > downs wrote: >> Try this. >> >> import std.gc; >> struct heapmalloc(T) { >> static T* opCall(U...)(U u) { >> auto res = cast(T*) malloc(T.sizeof); >> (*res) = T(u); >> return res; >> } >> } >> >> >> struct Foo { >> int a; >> float b; >> } >> >> void main() { >> auto heapfoo = heapmalloc!(Foo)(1984, 3.14159); >> } > > Or this. > > import std.gc; > > T* toHeap(T)(T st) { > auto res = cast(T*) malloc(T.sizeof); > (*res) = st; > return res; > } > > > struct Foo { > int a; > float b; > } > > void main() { auto th = toHeap(Foo(1984, 3.1415926)); assert(th.a == 1984); } > > :) > > --downs Or this! template heap() { import std.gc; typeof(this) heap() { auto res = cast(typeof(this)) malloc(typeof(*this).sizeof); (*res) = *this; return res; } } struct Foo { int a; float b; mixin heap!(); } void main() { auto th = Foo(1984, 3.1415926).heap; assert(th.a == 1984); }
Comment #4 by bugzilla — 2008-03-02T21:56:15Z
Marked as enhancement request.
Comment #5 by pro.mathias.lang — 2019-05-11T17:22:58Z
Great news everyone: struct have constructors (in D2)! D1 is retired tho.
Comment #6 by dlang-bot — 2020-02-07T14:37:29Z
dlang/dub pull request #1872 "Fix issue 1860: Main man page does not mention subcommands" was merged into master: - a1cb5e8fd240c794a3bd9127d3df351bf36f5946 by Geod24: Fix issue 1860: Main man page does not mention subcommands https://github.com/dlang/dub/pull/1872
Comment #7 by pro.mathias.lang — 2020-02-08T09:57:33Z
Thanks but no thanks dlang-bot