digitalmars.D.learn - Delay allocating class instance in stack.
- ANtlord (19/19) Mar 21 2017 Hello! I read documentation about memory management and can't
- rikki cattermole (2/2) Mar 21 2017 You probably want[0] to allocate a class on the stack instead of doing t...
- ANtlord (2/5) Mar 21 2017 If I will use it I won't use @nogc. Is the only one case?
- =?UTF-8?Q?Ali_=c3=87ehreli?= (26/36) Mar 21 2017 Another option is std.conv.emplace:
- ANtlord (3/22) Mar 21 2017 Thank you for clarification. But I have one more question. Do I
- =?UTF-8?Q?Ali_=c3=87ehreli?= (54/82) Mar 21 2017 Yes because what is going out of scope are two things:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (4/11) Mar 21 2017 Answering own question: There are two destructor calls because I call
- ANtlord (4/11) Mar 22 2017 Oh I got it. I have to use `destroy` in this case. If I use
- Nicholas Wilson (7/21) Mar 22 2017 You still have the buffer (the class has to go somewhere!), but
- ANtlord (9/16) Mar 22 2017 My bad. It appears I need to clarify. I mean the case that I
- Stefan Koch (6/25) Mar 21 2017 Try scope obj = new MyClass(flag ? 1 : 2);
- ANtlord (4/9) Mar 21 2017 Yes I know it. I prepare all input variables before construction
Hello! I read documentation about memory management and can't find description about delay allocation of instance. I have a method marked by nogc. This method takes boolean variable. If this variable is true I want to construct object with one set of parameters else I want to construct object with another set of parameters. Take a look at code for clearance. void method(bool flag) nogc { scope MyClass obj; if(flag) { obj = new MyClass(1); } else { obj = new MyClass(2); } // using obj } But this code CAN'T be compiled. How should I declare object for delay construction. Thanks.
Mar 21 2017
You probably want[0] to allocate a class on the stack instead of doing this.
Mar 21 2017
On Tuesday, 21 March 2017 at 08:12:36 UTC, rikki cattermole wrote:You probably want[0] to allocate a class on the stack instead of doing this.If I will use it I won't use nogc. Is the only one case?
Mar 21 2017
On 03/21/2017 01:08 AM, ANtlord wrote:void method(bool flag) nogc { scope MyClass obj; if(flag) { obj = new MyClass(1); } else { obj = new MyClass(2); } // using obj }Another option is std.conv.emplace: import std.conv : emplace; class MyClass { this(int) nogc { } ~this() nogc { } } void method(bool flag) nogc { void[__traits(classInstanceSize, MyClass)] buffer = void; MyClass obj; if(flag) { obj = emplace!MyClass(buffer, 1); } else { obj = emplace!MyClass(buffer, 2); } // Unfortunately, destroy() is not nogc // scope(exit) destroy(obj); } void main() { method(false); method(true); } Ali
Mar 21 2017
On Tuesday, 21 March 2017 at 08:46:43 UTC, Ali Çehreli wrote:Another option is std.conv.emplace: import std.conv : emplace; class MyClass { this(int) nogc { } ~this() nogc { } } void method(bool flag) nogc { void[__traits(classInstanceSize, MyClass)] buffer = void; MyClass obj; if(flag) { obj = emplace!MyClass(buffer, 1); } else { obj = emplace!MyClass(buffer, 2); } // Unfortunately, destroy() is not nogc // scope(exit) destroy(obj);Thank you for clarification. But I have one more question. Do I have to use destroy for deallocating object from stack?
Mar 21 2017
On 03/21/2017 09:57 PM, ANtlord wrote:On Tuesday, 21 March 2017 at 08:46:43 UTC, Ali Çehreli wrote:Yes because what is going out of scope are two things: - A buffer - A MyClass reference Neither of those have destructors. (emplace is just a library function that does something with that buffer but the compiler cannot know that there is an object that we want destructed.) Here is a hack that defines a destroyNoGC() that allows one to call the destructor is a nogc context: import std.stdio; import std.conv : emplace; class MyClass { this(int) nogc { } ~this() nogc { printf("~this\n"); } } // Adapted from std.traits.SetFunctionAttributes documentation import std.traits; auto assumeNoGC(T)(T t) if (isFunctionPointer!T || isDelegate!T) { enum attrs = functionAttributes!T | FunctionAttribute.nogc; return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t; } nogc void function(Object) destroyNoGC; static this() { destroyNoGC = assumeNoGC((Object obj) { destroy(obj); }); } void method(bool flag) nogc { void[__traits(classInstanceSize, MyClass)] buffer = void; MyClass obj; if(flag) { obj = emplace!MyClass(buffer, 1); } else { obj = emplace!MyClass(buffer, 2); } scope(exit) { destroyNoGC(obj); } } void main() { method(false); method(true); } Gotta love D for allowing such code but it comes with surprises. Why do we suddenly get two destructor calls? ~this ~this AliAnother option is std.conv.emplace: import std.conv : emplace; class MyClass { this(int) nogc { } ~this() nogc { } } void method(bool flag) nogc { void[__traits(classInstanceSize, MyClass)] buffer = void; MyClass obj; if(flag) { obj = emplace!MyClass(buffer, 1); } else { obj = emplace!MyClass(buffer, 2); } // Unfortunately, destroy() is not nogc // scope(exit) destroy(obj);Thank you for clarification. But I have one more question. Do I have to use destroy for deallocating object from stack?
Mar 21 2017
On 03/21/2017 11:47 PM, Ali Çehreli wrote:method(false); method(true); } Gotta love D for allowing such code but it comes with surprises. Why do we suddenly get two destructor calls? ~this ~thisAnswering own question: There are two destructor calls because I call method() twice. Ali
Mar 21 2017
On Wednesday, 22 March 2017 at 06:47:26 UTC, Ali Çehreli wrote:On 03/21/2017 09:57 PM, ANtlord wrote:Oh I got it. I have to use `destroy` in this case. If I use `scope` I haven't buffer and MyClass reference then I can don't use `destroy`. Do I understand correctly?Thank you for clarification. But I have one more question. DoI have touse destroy for deallocating object from stack?Yes because what is going out of scope are two things: - A buffer - A MyClass reference
Mar 22 2017
On Wednesday, 22 March 2017 at 08:57:34 UTC, ANtlord wrote:On Wednesday, 22 March 2017 at 06:47:26 UTC, Ali Çehreli wrote:You still have the buffer (the class has to go somewhere!), but it is implicit (you can't refer to it directly only through the class reference) and so is the destructor call, as opposed to the emplace + explicit buffer combo. In the latter case the class destructor will not be called automatically so you must do it yourself with `destroy`.On 03/21/2017 09:57 PM, ANtlord wrote:Oh I got it. I have to use `destroy` in this case. If I use `scope` I haven't buffer and MyClass reference then I can don't use `destroy`. Do I understand correctly?Thank you for clarification. But I have one more question. DoI have touse destroy for deallocating object from stack?Yes because what is going out of scope are two things: - A buffer - A MyClass reference
Mar 22 2017
On Wednesday, 22 March 2017 at 13:19:32 UTC, Nicholas Wilson wrote:On Wednesday, 22 March 2017 at 08:57:34 UTC, ANtlord wrote:You still have the buffer (the class has to go somewhere!), but it is implicit (you can't refer to it directly only through the class reference) and so is the destructor call, as opposed to the emplace + explicit buffer combo. In the latter case the class destructor will not be called automatically so you must do it yourself with `destroy`.My bad. It appears I need to clarify. I mean the case that I create object without delaying. I mean simple construction. scope myObj = MyClass(1); Answering own question: In this case object is allocated using stack (according documention https://wiki.dlang.org/Memory_Management#Allocating_Class_Inst nces_On_The_Stack). Function `destroy` used for cleanup object from heap (according documention https://wiki.dlang.org/Memory_Management#Explicit_Class_Instance_Allocation).
Mar 22 2017
On Tuesday, 21 March 2017 at 08:08:24 UTC, ANtlord wrote:Hello! I read documentation about memory management and can't find description about delay allocation of instance. I have a method marked by nogc. This method takes boolean variable. If this variable is true I want to construct object with one set of parameters else I want to construct object with another set of parameters. Take a look at code for clearance. void method(bool flag) nogc { scope MyClass obj; if(flag) { obj = new MyClass(1); } else { obj = new MyClass(2); } // using obj } But this code CAN'T be compiled. How should I declare object for delay construction. Thanks.Try scope obj = new MyClass(flag ? 1 : 2); In essence you should never need to delay construction. Just construct the object as soon as you have everything to construct it. which includes conditions.
Mar 21 2017
On Tuesday, 21 March 2017 at 12:30:57 UTC, Stefan Koch wrote:Try scope obj = new MyClass(flag ? 1 : 2); In essence you should never need to delay construction. Just construct the object as soon as you have everything to construct it. which includes conditions.Yes I know it. I prepare all input variables before construction of object usually. I just want to know possibilty of the case described above.
Mar 21 2017