digitalmars.D.learn - Create class on stack
- Johnson Jones (7/7) Aug 05 2017 using gtk, it has a type called value. One has to use it to get
- angel (3/10) Aug 05 2017 Emplace ?
- Moritz Maxeiner (4/11) Aug 05 2017 The easy way is through std.typecons.scoped [1].
- Johnson Jones (3/15) Aug 05 2017 Thanks, I didn't think it created on the stack but it makes sense
- Moritz Maxeiner (7/28) Aug 05 2017 See the source [1] as to why: typeof(scoped!T) is a
- FoxyBrown (11/40) Aug 05 2017 I don't think you understand what I'm saying.
- Adam D. Ruppe (5/9) Aug 05 2017 compile time. It works like a static array of the appropriate
- FoxyBrown (4/13) Aug 05 2017 yeah, I know, but no need for it ;) Still better than the heap
- Moritz Maxeiner (3/9) Aug 06 2017 It's the only one I'm aware of OTTOMH. If you encounter others, a
- Jacob Carlborg (5/10) Aug 06 2017 Prefix the variable declaration with "scope":
- Moritz Maxeiner (7/21) Aug 06 2017 If you use this option, do be aware that this feature has been
- Jacob Carlborg (4/7) Aug 07 2017 It's used all over the place in the DMD code base.
- Moritz Maxeiner (6/13) Aug 07 2017 I don't see how that's a reason for increasing the amount of code
- Mike (7/13) Aug 07 2017 FYI: http://forum.dlang.org/post/np1fll$ast$1@digitalmars.com
- Moritz Maxeiner (61/74) Aug 07 2017 Thanks, I wasn't aware of this. I tried fooling around scope
- Moritz Maxeiner (27/87) Aug 07 2017 Forgot to add the runtime output after compiling with `dmd a.d
- Mike (5/11) Aug 07 2017 Looks like a bug to me. I recommend submitting a bug report and
- Moritz Maxeiner (3/13) Aug 07 2017 Thanks for the feedback, done:
- Johan Engelen (43/50) Aug 08 2017 Thanks for the test case :-)
- ANtlord (4/9) Aug 07 2017 I can't understand. Why is moved a scope allocation to a library.
- Moritz Maxeiner (20/30) Aug 08 2017 The reason is given at the link under "Rationale":
using gtk, it has a type called value. One has to use it to get the value of stuff but it is a class. Once it is used, one doesn't need it. Ideally I'd like to treat it as a struct since I'm using it in a delegate I would like to minimize unnecessary allocations. Is there any way to get D to allocate a class on the stack like a local struct?
Aug 05 2017
On Saturday, 5 August 2017 at 17:08:32 UTC, Johnson Jones wrote:using gtk, it has a type called value. One has to use it to get the value of stuff but it is a class. Once it is used, one doesn't need it. Ideally I'd like to treat it as a struct since I'm using it in a delegate I would like to minimize unnecessary allocations. Is there any way to get D to allocate a class on the stack like a local struct?Emplace ? https://dlang.org/phobos/std_conv.html#emplace
Aug 05 2017
On Saturday, 5 August 2017 at 17:08:32 UTC, Johnson Jones wrote:using gtk, it has a type called value. One has to use it to get the value of stuff but it is a class. Once it is used, one doesn't need it. Ideally I'd like to treat it as a struct since I'm using it in a delegate I would like to minimize unnecessary allocations. Is there any way to get D to allocate a class on the stack like a local struct?The easy way is through std.typecons.scoped [1]. Here be dragons, though, because classes are reference types. [1] https://dlang.org/phobos/std_typecons.html#.scoped
Aug 05 2017
On Saturday, 5 August 2017 at 23:09:09 UTC, Moritz Maxeiner wrote:On Saturday, 5 August 2017 at 17:08:32 UTC, Johnson Jones wrote:Thanks, I didn't think it created on the stack but it makes sense to do so. The only issue is that it escaping the reference?using gtk, it has a type called value. One has to use it to get the value of stuff but it is a class. Once it is used, one doesn't need it. Ideally I'd like to treat it as a struct since I'm using it in a delegate I would like to minimize unnecessary allocations. Is there any way to get D to allocate a class on the stack like a local struct?The easy way is through std.typecons.scoped [1]. Here be dragons, though, because classes are reference types. [1] https://dlang.org/phobos/std_typecons.html#.scoped
Aug 05 2017
On Sunday, 6 August 2017 at 01:18:50 UTC, Johnson Jones wrote:On Saturday, 5 August 2017 at 23:09:09 UTC, Moritz Maxeiner wrote:See the source [1] as to why: typeof(scoped!T) is a (non-copyable) struct that holds the memory for the T object inside it.On Saturday, 5 August 2017 at 17:08:32 UTC, Johnson Jones wrote:Thanks, I didn't think it created on the stack but it makes sense to do so.using gtk, it has a type called value. One has to use it to get the value of stuff but it is a class. Once it is used, one doesn't need it. Ideally I'd like to treat it as a struct since I'm using it in a delegate I would like to minimize unnecessary allocations. Is there any way to get D to allocate a class on the stack like a local struct?The easy way is through std.typecons.scoped [1]. Here be dragons, though, because classes are reference types. [1] https://dlang.org/phobos/std_typecons.html#.scopedThe only issue is that it escaping the reference?Yes, don't escape references, that's the reason for my comment:[1] https://github.com/dlang/phobos/blob/v2.075.0/std/typecons.d#L6613Here be dragons, though, because classes are reference types.
Aug 05 2017
On Sunday, 6 August 2017 at 02:10:31 UTC, Moritz Maxeiner wrote:On Sunday, 6 August 2017 at 01:18:50 UTC, Johnson Jones wrote:I don't think you understand what I'm saying. If I use this method to create a "reference" type on the stack rather than the heap, is the only issue worrying about not having that variable be used outside that scope(i.e., have it "escape")? Obviously since it's on the stack it will be invalid after the function call, but I'm talking about other pitfalls. I don't see any but I want to be sure. Also, does it do the allocation at compile time(reserve space on the stack for the variable along with all the others or does it "allocate" space on the stack at runtime?... which is slightly slower).On Saturday, 5 August 2017 at 23:09:09 UTC, Moritz Maxeiner wrote:See the source [1] as to why: typeof(scoped!T) is a (non-copyable) struct that holds the memory for the T object inside it.On Saturday, 5 August 2017 at 17:08:32 UTC, Johnson Jones wrote:Thanks, I didn't think it created on the stack but it makes sense to do so.using gtk, it has a type called value. One has to use it to get the value of stuff but it is a class. Once it is used, one doesn't need it. Ideally I'd like to treat it as a struct since I'm using it in a delegate I would like to minimize unnecessary allocations. Is there any way to get D to allocate a class on the stack like a local struct?The easy way is through std.typecons.scoped [1]. Here be dragons, though, because classes are reference types. [1] https://dlang.org/phobos/std_typecons.html#.scopedThe only issue is that it escaping the reference?Yes, don't escape references, that's the reason for my comment:[1] https://github.com/dlang/phobos/blob/v2.075.0/std/typecons.d#L6613Here be dragons, though, because classes are reference types.
Aug 05 2017
On Sunday, 6 August 2017 at 02:19:19 UTC, FoxyBrown wrote:Also, does it do the allocation at compile time(reserve space on the stack for the variable along with all the others or does it "allocate" space on the stack at runtime?... which is slightly slower).compile time. It works like a static array of the appropriate size. though the cost if ti was at runtime is small regardless. I think it is just a register subtract.
Aug 05 2017
On Sunday, 6 August 2017 at 02:32:05 UTC, Adam D. Ruppe wrote:On Sunday, 6 August 2017 at 02:19:19 UTC, FoxyBrown wrote:yeah, I know, but no need for it ;) Still better than the heap but was just curious ;) No need to waste cycles if it's not necessary.Also, does it do the allocation at compile time(reserve space on the stack for the variable along with all the others or does it "allocate" space on the stack at runtime?... which is slightly slower).compile time. It works like a static array of the appropriate size. though the cost if ti was at runtime is small regardless. I think it is just a register subtract.
Aug 05 2017
On Sunday, 6 August 2017 at 02:19:19 UTC, FoxyBrown wrote:[...] I don't think you understand what I'm saying. If I use this method to create a "reference" type on the stack rather than the heap, is the only issue worrying about not having that variable be used outside that scope(i.e., have it "escape")?It's the only one I'm aware of OTTOMH. If you encounter others, a bug report would be appreciated.
Aug 06 2017
On 2017-08-05 19:08, Johnson Jones wrote:using gtk, it has a type called value. One has to use it to get the value of stuff but it is a class. Once it is used, one doesn't need it. Ideally I'd like to treat it as a struct since I'm using it in a delegate I would like to minimize unnecessary allocations. Is there any way to get D to allocate a class on the stack like a local struct?Prefix the variable declaration with "scope": scope foo = new Object; -- /Jacob Carlborg
Aug 06 2017
On Sunday, 6 August 2017 at 15:24:55 UTC, Jacob Carlborg wrote:On 2017-08-05 19:08, Johnson Jones wrote:If you use this option, do be aware that this feature has been scheduled for future deprecation [1]. It's likely going to continue working for quite a while (years), though. [1] https://dlang.org/deprecate.html#scope%20for%20allocating%20classes%20on%20the%20stackusing gtk, it has a type called value. One has to use it to get the value of stuff but it is a class. Once it is used, one doesn't need it. Ideally I'd like to treat it as a struct since I'm using it in a delegate I would like to minimize unnecessary allocations. Is there any way to get D to allocate a class on the stack like a local struct?Prefix the variable declaration with "scope": scope foo = new Object;
Aug 06 2017
On 2017-08-06 17:47, Moritz Maxeiner wrote:If you use this option, do be aware that this feature has been scheduled for future deprecation [1]. It's likely going to continue working for quite a while (years), though.It's used all over the place in the DMD code base. -- /Jacob Carlborg
Aug 07 2017
On Monday, 7 August 2017 at 10:42:03 UTC, Jacob Carlborg wrote:On 2017-08-06 17:47, Moritz Maxeiner wrote:I don't see how that's a reason for increasing the amount of code that needs to be changed if/when scope classes are deprecated. Mike's argument holds, though (if the loophole I pointed out gets fixed and scope classes are removed from the future deprecation list).If you use this option, do be aware that this feature has been scheduled for future deprecation [1]. It's likely going to continue working for quite a while (years), though.It's used all over the place in the DMD code base.
Aug 07 2017
On Sunday, 6 August 2017 at 15:47:43 UTC, Moritz Maxeiner wrote:If you use this option, do be aware that this feature has been scheduled for future deprecation [1]. It's likely going to continue working for quite a while (years), though. [1] https://dlang.org/deprecate.html#scope%20for%20allocating%20classes%20on%20the%20stackFYI: http://forum.dlang.org/post/np1fll$ast$1 digitalmars.com "Yes, it will have to be updated - but I didn't want to adjust it before DIP1000 spec is finalized. Rationale that was driving deprecation of scope storage class is becoming obsolete with DIP1000 implemented but not before." Mike
Aug 07 2017
On Monday, 7 August 2017 at 10:50:21 UTC, Mike wrote:On Sunday, 6 August 2017 at 15:47:43 UTC, Moritz Maxeiner wrote:Thanks, I wasn't aware of this. I tried fooling around scope classes and DIP1000 for a bit and was surprised that this is allowed: --- import core.stdc.stdio : printf; import std.algorithm : move; class A { int i; this() safe { i = 0; } } void inc(scope A a) safe { a.i += 1; } void print(scope A a) trusted { printf("A %x: %d\n", cast(void*) a, a.i); } auto makeA() safe { scope a = new A(); a.print(); return move(a); } void main() safe { auto a = makeA(); foreach (i; 0..10) { a.print(); a.inc(); } } --- You can still create a (scope) class on the stack, escape a reference to it using `move` and use it afterwards, all within the rules of safe, so I'm not convinced that the reason for deprecating scoped classes is gone yet. Compare this to `scoped`, which behaves as expected (since it wraps the reference type object in a value type): --- import std.typecons : scoped; auto makeA() trusted { auto a = scoped!A(); a.print(); return move(a); } void main() trusted { auto a = makeA(); foreach (i; 0..10) { a.print(); a.inc(); } } ---If you use this option, do be aware that this feature has been scheduled for future deprecation [1]. It's likely going to continue working for quite a while (years), though. [1] https://dlang.org/deprecate.html#scope%20for%20allocating%20classes%20on%20the%20stackFYI: http://forum.dlang.org/post/np1fll$ast$1 digitalmars.com "Yes, it will have to be updated - but I didn't want to adjust it before DIP1000 spec is finalized. Rationale that was driving deprecation of scope storage class is becoming obsolete with DIP1000 implemented but not before."
Aug 07 2017
On Monday, 7 August 2017 at 13:40:18 UTC, Moritz Maxeiner wrote:Thanks, I wasn't aware of this. I tried fooling around scope classes and DIP1000 for a bit and was surprised that this is allowed: --- import core.stdc.stdio : printf; import std.algorithm : move; class A { int i; this() safe { i = 0; } } void inc(scope A a) safe { a.i += 1; } void print(scope A a) trusted { printf("A %x: %d\n", cast(void*) a, a.i); } auto makeA() safe { scope a = new A(); a.print(); return move(a); } void main() safe { auto a = makeA(); foreach (i; 0..10) { a.print(); a.inc(); } } --- You can still create a (scope) class on the stack, escape a reference to it using `move` and use it afterwards, all within the rules of safe, so I'm not convinced that the reason for deprecating scoped classes is gone yet. Compare this to `scoped`, which behaves as expected (since it wraps the reference type object in a value type): --- import std.typecons : scoped; auto makeA() trusted { auto a = scoped!A(); a.print(); return move(a); } void main() trusted { auto a = makeA(); foreach (i; 0..10) { a.print(); a.inc(); } } ---Forgot to add the runtime output after compiling with `dmd a.d -dip1000`: For `scope A`: A 198d1568: 0 A 198d1568: 0 A 198d1568: 1 A 198d1568: 2 A 198d1568: 3 A 198d1568: 4 A 198d1568: 5 A 198d1568: 6 A 198d1568: 7 A 198d1568: 8 A 198d1568: 9 For `scoped!A`: A 8de538b8: 0 A 8de53940: 0 A 8de53940: 1 A 8de53940: 2 A 8de53940: 3 A 8de53940: 4 A 8de53940: 5 A 8de53940: 6 A 8de53940: 7 A 8de53940: 8 A 8de53940: 9
Aug 07 2017
On Monday, 7 August 2017 at 13:42:33 UTC, Moritz Maxeiner wrote:Looks like a bug to me. I recommend submitting a bug report and tag it somehow with "scope" and/or "DIP1000". It appears Walter is giving any bugs with scope/DIP1000 priority. MikeYou can still create a (scope) class on the stack, escape a reference to it using `move` and use it afterwards, all within the rules of safe, so I'm not convinced that the reason for deprecating scoped classes is gone yet. Compare this to `scoped`, which behaves as expected (since it wraps the reference type object in a value type):
Aug 07 2017
On Monday, 7 August 2017 at 22:02:07 UTC, Mike wrote:On Monday, 7 August 2017 at 13:42:33 UTC, Moritz Maxeiner wrote:Thanks for the feedback, done: https://issues.dlang.org/show_bug.cgi?id=17730Looks like a bug to me. I recommend submitting a bug report and tag it somehow with "scope" and/or "DIP1000". It appears Walter is giving any bugs with scope/DIP1000 priority.You can still create a (scope) class on the stack, escape a reference to it using `move` and use it afterwards, all within the rules of safe, so I'm not convinced that the reason for deprecating scoped classes is gone yet. Compare this to `scoped`, which behaves as expected (since it wraps the reference type object in a value type):
Aug 07 2017
On Monday, 7 August 2017 at 13:40:18 UTC, Moritz Maxeiner wrote:Thanks, I wasn't aware of this. I tried fooling around scope classes and DIP1000 for a bit and was surprised that this is allowed:Thanks for the test case :-) It was fun to see that ASan can catch this bug too. Because writing the blog post about ASan will take quite some time still, I've pasted the demonstration below (there is a big big big caveat that will need more work from LDC's side, but you'll have to wait until the blog article). Simplified your code for the demonstration: ``` class A { int i; } void inc(A a) safe { a.i += 1; // Line 6 } auto makeA() safe { // Line 9 import std.algorithm : move; scope a = new A(); return move(a); } void main() safe { auto a = makeA(); a.inc(); // Line 17 } ``` ```ldc2 -fsanitize=address -disable-fp-elim scopeclass.d -g -O1 -dip1000 ASAN_OPTIONS=detect_stack_use_after_return=1 ./scopeclass 2>&1 | ddemangle================================================================= ==11446==ERROR: AddressSanitizer: stack-use-after-return on address 0x000104929050 at pc 0x0001007a9837 bp 0x7fff5f457510 sp 0x7fff5f457508 READ of size 4 at 0x000104929050 thread T0 scopeclass.d:6 _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv (scopeclass:x86_64+0x10013c0ce) Address 0x000104929050 is located in stack of thread T0 at offset 80 in frame scopeclass.makeA() scopeclass.d:9 ```
Aug 08 2017
On Sunday, 6 August 2017 at 15:47:43 UTC, Moritz Maxeiner wrote:If you use this option, do be aware that this feature has been> scheduled for future deprecation [1].It's likely going to continue working for quite a while (years), though. [1] https://dlang.org/deprecate.html#scope%20for%20allocating%20classes%20on%20the%20stackI can't understand. Why is moved a scope allocation to a library. I'm pretty sure it should be a language feature.
Aug 07 2017
On Tuesday, 8 August 2017 at 05:37:41 UTC, ANtlord wrote:On Sunday, 6 August 2017 at 15:47:43 UTC, Moritz Maxeiner wrote:The reason is given at the link under "Rationale": --- scope was an unsafe feature. A reference to a scoped class could easily be returned from a function without errors, which would make using such an object undefined behavior due to the object being destroyed after exiting the scope of the function it was allocated in. To discourage it from general-use but still allow usage when needed a library solution was implemented. Note that scope for other usages (e.g. scoped variables) is unrelated to this feature and will not be deprecated. --- Do note that - as Mike pointed out - this rationale does predate DIP1000 escape analysis and is largely invalidated by it for safe code. Another reason to use the library type is the ability to move the class object around via std.algorithm.move (if you need such C++ style behaviour); I'm not sure whether scope classes will get this feature (I have argued for it at the bug report linked to in my response to Mike), but I wouldn't count on it.If you use this option, do be aware that this feature has been> scheduled for future deprecation [1].It's likely going to continue working for quite a while (years), though. [1] https://dlang.org/deprecate.html#scope%20for%20allocating%20classes%20on%20the%20stackI can't understand. Why is moved a scope allocation to a library. I'm pretty sure it should be a language feature.
Aug 08 2017