digitalmars.D.learn - How to allocate an element of type T with value x in generic code?
- Tobias Pankrath (10/10) Apr 03 2013 basic idea.
- John Colvin (5/15) Apr 03 2013 Do you need to use new? i.e. do you need the variable to be
- Tobias Pankrath (9/26) Apr 03 2013 I need a fresh T (let's call it t) allocated on the heap and a
- John Colvin (12/39) Apr 03 2013 int* pt = new T; //that will only compile if T is int. I assume
- Andrej Mitrovic (3/5) Apr 03 2013 Shouldn't that call be GC.malloc? I don't see a module-scoped malloc
- John Colvin (2/8) Apr 03 2013 yes, you are correct.
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (29/35) Apr 03 2013 That assignment will fail in general when the left-hand side has those
- John Colvin (2/4) Apr 03 2013 Could you expand on this? I don't fully understand.
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (40/44) Apr 03 2013 In short, there is no object on the left-hand side.
- Tobias Pankrath (1/1) Apr 03 2013 Thank you for the answers, helped a lot!
- Steven Schveighoffer (8/18) Apr 03 2013 A crude but easy way to do this:
basic idea. --- T x; T* px = new T(x); --- int x int* px = new int(x); // fails --- I need to do this for structs and basic types. What's the standard way to do this?
Apr 03 2013
On Wednesday, 3 April 2013 at 11:05:06 UTC, Tobias Pankrath wrote:basic idea. --- T x; T* px = new T(x); --- int x int* px = new int(x); // fails --- I need to do this for structs and basic types. What's the standard way to do this?Do you need to use new? i.e. do you need the variable to be allocated on the heap? Also, as you've written it, px is not a pointer to x which is a bit misleading. What is the result you actually want?
Apr 03 2013
On Wednesday, 3 April 2013 at 14:47:22 UTC, John Colvin wrote:On Wednesday, 3 April 2013 at 11:05:06 UTC, Tobias Pankrath wrote:I need a fresh T (let's call it t) allocated on the heap and a pointer (pt) to it and the value of t should be the value of x. --- T x; int* pt = new T; *pt = x; --- Maybe I'll just do this.basic idea. --- T x; T* px = new T(x); --- int x int* px = new int(x); // fails --- I need to do this for structs and basic types. What's the standard way to do this?Do you need to use new? i.e. do you need the variable to be allocated on the heap? Also, as you've written it, px is not a pointer to x which is a bit misleading. What is the result you actually want?
Apr 03 2013
On Wednesday, 3 April 2013 at 15:25:22 UTC, Tobias Pankrath wrote:On Wednesday, 3 April 2013 at 14:47:22 UTC, John Colvin wrote:int* pt = new T; //that will only compile if T is int. I assume you meant: T* pt = new T; Other than that, what you have done there should work. To avoid any superfluous initialisation of fields: import core.memory : malloc; T x; T* pt = cast(T*)malloc(T.sizeof); *pt = x; note: this is not C malloc, the memory is requested from and managed by the GC.On Wednesday, 3 April 2013 at 11:05:06 UTC, Tobias Pankrath wrote:I need a fresh T (let's call it t) allocated on the heap and a pointer (pt) to it and the value of t should be the value of x. --- T x; int* pt = new T; *pt = x; --- Maybe I'll just do this.basic idea. --- T x; T* px = new T(x); --- int x int* px = new int(x); // fails --- I need to do this for structs and basic types. What's the standard way to do this?Do you need to use new? i.e. do you need the variable to be allocated on the heap? Also, as you've written it, px is not a pointer to x which is a bit misleading. What is the result you actually want?
Apr 03 2013
On 4/3/13, John Colvin <john.loughran.colvin gmail.com> wrote:note: this is not C malloc, the memory is requested from and managed by the GC.Shouldn't that call be GC.malloc? I don't see a module-scoped malloc function anywhere except the C one in core.stdc.stdlib.
Apr 03 2013
On Wednesday, 3 April 2013 at 16:13:02 UTC, Andrej Mitrovic wrote:On 4/3/13, John Colvin <john.loughran.colvin gmail.com> wrote:yes, you are correct.note: this is not C malloc, the memory is requested from and managed by the GC.Shouldn't that call be GC.malloc? I don't see a module-scoped malloc function anywhere except the C one in core.stdc.stdlib.
Apr 03 2013
On 04/03/2013 08:53 AM, John Colvin wrote:import core.memory : malloc; T x; T* pt = cast(T*)malloc(T.sizeof); *pt = x; note: this is not C malloc, the memory is requested from and managed by the GC.That assignment will fail in general when the left-hand side has those undetermined bits. std.conv.emplace is a safer option but it must be used differently for classes. import std.stdio; import core.memory; import std.conv; T * makeNew(T)(T rhs) { static if (is(T == class)) { static assert(false); // not implemented } else { T * p = cast(T*)GC.calloc(T.sizeof); emplace!T(p, rhs); return p; } } struct S { int i; } void main() { writeln(*makeNew(42)); writeln(*makeNew(1.5)); writeln(*makeNew(S(1))); } The program should consider __traits(classInstanceSize) for classes. Ali
Apr 03 2013
On Wednesday, 3 April 2013 at 16:39:18 UTC, Ali Çehreli wrote:That assignment will fail in general when the left-hand side has those undetermined bits.Could you expand on this? I don't fully understand.
Apr 03 2013
On 04/03/2013 10:19 AM, John Colvin wrote:On Wednesday, 3 April 2013 at 16:39:18 UTC, Ali Çehreli wrote:In short, there is no object on the left-hand side. GC.malloc() does not initialize the memory that it allocates. Assignment involves destroying the lhs object. (It is two operations packaged together: copy the right-hand side and destroy the left-hand side.) If the uninitialized bits in the newly-allocated memory were invalid for T, then the destruction will fail or do something wrong. The following program is sure to fail because 'fileName' happens to be a bad string when opAssign() is entered: // WARNING: Your system may become unresponsive if you execute this program import std.stdio; import core.memory; import std.exception; import std.array; struct S { string fileName; this(string fileName) { enforce(!fileName.empty); } ref S opAssign(S rhs) { writefln("Stop using file %s", fileName); this.fileName = rhs.fileName; writefln("Start using file %s", fileName); return this; } ~this() { writefln("Destroying S with %s", fileName); } } void main() { auto x = S("abc"); S* pt = cast(S*)GC.malloc(S.sizeof); *pt = x; } AliThat assignment will fail in general when the left-hand side has those undetermined bits.Could you expand on this? I don't fully understand.
Apr 03 2013
Thank you for the answers, helped a lot!
Apr 03 2013
On Wed, 03 Apr 2013 07:05:05 -0400, Tobias Pankrath <tobias pankrath.net> wrote:basic idea. --- T x; T* px = new T(x); --- int x int* px = new int(x); // fails --- I need to do this for structs and basic types. What's the standard way to do this?A crude but easy way to do this: int *px = [x].ptr; Only caveat is that the allocated block may be slightly bigger than necessary. If you are concerned about footprint, you may want to do it with GC.malloc calls directly. -Steve
Apr 03 2013