www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Classes on stack

reply Redwan <rdwnsjjd gmail.com> writes:
Hi all
I'm new to D from c, cpp and Rust.

this language made me surprised because of its features and 
syntax and etc.

but I shocked when I found that classes must be created only on 
stack! Is this nightmare real? why???
I want declare classes and create instance of them on stack and 
nicely use them. why I must put them on heap??
structs does not support inheritance and I don't want to use 
them. please tell me that is not true or give me some other ways. 
I don't want define objects always on heap. don't let me go back 
on cpp :( tnx!
Sep 01 2022
next sibling parent reply Dennis <dkorpel gmail.com> writes:
On Thursday, 1 September 2022 at 09:13:56 UTC, Redwan wrote:
 I want declare classes and create instance of them on stack and 
 nicely use them.
You can use that using the `scope` storage class on a local variable with a class type: https://dlang.org/spec/attribute.html#scope-class-var ```D void main() nogc { scope o = new Object(); } ``` The ` nogc` attribute ensures no allocations are made with the Garbage Collector.
Sep 01 2022
parent reply Redwan <rdwnsjjd gmail.com> writes:
On Thursday, 1 September 2022 at 09:40:06 UTC, Dennis wrote:
 On Thursday, 1 September 2022 at 09:13:56 UTC, Redwan wrote:
 I want declare classes and create instance of them on stack 
 and nicely use them.
You can use that using the `scope` storage class on a local variable with a class type: https://dlang.org/spec/attribute.html#scope-class-var ```D void main() nogc { scope o = new Object(); } ``` The ` nogc` attribute ensures no allocations are made with the Garbage Collector.
oh, thank you. with this, no allocation??
Sep 01 2022
next sibling parent reply Dennis <dkorpel gmail.com> writes:
On Thursday, 1 September 2022 at 09:43:55 UTC, Redwan wrote:
 oh, thank you. with this, no allocation??
No heap allocation. The ` nogc` attribute is enforced by the compiler, so you will get an error if you use `new` without `scope` here.
Sep 01 2022
parent reply Redwan <rdwnsjjd gmail.com> writes:
On Thursday, 1 September 2022 at 09:53:08 UTC, Dennis wrote:
 On Thursday, 1 September 2022 at 09:43:55 UTC, Redwan wrote:
 oh, thank you. with this, no allocation??
No heap allocation. The ` nogc` attribute is enforced by the compiler, so you will get an error if you use `new` without `scope` here.
OK tnx. another problem that probably is related to this issue. I compiled this worthless code: ``` void main() {} ``` also this one: ``` nogc void main() {} ``` the valgrind result: ``` ... total heap usage: 143 alloc, 141 frees, 13,236 bytes allocated ... ``` !!! what's this means?? from where comes this allocations and also leaks??? if it's for GC, how to completely disable gc? I don't Wan use it at all. I searched for a compiler command line disabling for gc but not found. GC.disable() is ugly way I think.
Sep 01 2022
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 01/09/2022 10:13 PM, Redwan wrote:
 if it's for GC, how to completely disable gc? I don't Wan use it at all. 
 I searched for a compiler command line disabling for gc but not found. 
 GC.disable() is ugly way I think.
As long as you want to use things like classes and Phobos, you're stuck with the GC being linked in and active at some point in the lifetime of your process. D's runtime includes a lot of infrastructure such as threading that is initialized before your main ever executes. You can limit the GC activity by things like GC.disable, but its still linked in and in use at some point in time. D's GC is your friend, if you don't allocate it won't attempt to collect unless you want it to.
Sep 01 2022
next sibling parent reply Redwan <rdwnsjjd gmail.com> writes:
On Thursday, 1 September 2022 at 10:21:32 UTC, rikki cattermole 
wrote:
 On 01/09/2022 10:13 PM, Redwan wrote:
 if it's for GC, how to completely disable gc? I don't Wan use 
 it at all. I searched for a compiler command line disabling 
 for gc but not found. GC.disable() is ugly way I think.
As long as you want to use things like classes and Phobos, you're stuck with the GC being linked in and active at some point in the lifetime of your process. D's runtime includes a lot of infrastructure such as threading that is initialized before your main ever executes. You can limit the GC activity by things like GC.disable, but its still linked in and in use at some point in time. D's GC is your friend, if you don't allocate it won't attempt to collect unless you want it to.
well I know it's my friend, but we're just friend :) I don't want to use it because it's uses alot of heap and I don't like it. my case is special and all of heap usages needs to be done by me. so I want to do something to avoid this dynamic and runtime linkages and etc and be pure and in my hand. definitely it must be some flags or configurations to disable this stuff for a system language. am I right?
Sep 01 2022
next sibling parent reply bauss <jacobbauss gmail.com> writes:
On Thursday, 1 September 2022 at 10:51:44 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 10:21:32 UTC, rikki cattermole 
 wrote:
 On 01/09/2022 10:13 PM, Redwan wrote:
 if it's for GC, how to completely disable gc? I don't Wan use 
 it at all. I searched for a compiler command line disabling 
 for gc but not found. GC.disable() is ugly way I think.
As long as you want to use things like classes and Phobos, you're stuck with the GC being linked in and active at some point in the lifetime of your process. D's runtime includes a lot of infrastructure such as threading that is initialized before your main ever executes. You can limit the GC activity by things like GC.disable, but its still linked in and in use at some point in time. D's GC is your friend, if you don't allocate it won't attempt to collect unless you want it to.
well I know it's my friend, but we're just friend :) I don't want to use it because it's uses alot of heap and I don't like it. my case is special and all of heap usages needs to be done by me. so I want to do something to avoid this dynamic and runtime linkages and etc and be pure and in my hand. definitely it must be some flags or configurations to disable this stuff for a system language. am I right?
I already gave you the solution one message above; betterC (A subset of D) is what you want.
Sep 01 2022
parent reply Redwan <rdwnsjjd gmail.com> writes:
On Thursday, 1 September 2022 at 11:06:31 UTC, bauss wrote:
 On Thursday, 1 September 2022 at 10:51:44 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 10:21:32 UTC, rikki 
 cattermole wrote:
 On 01/09/2022 10:13 PM, Redwan wrote:
 if it's for GC, how to completely disable gc? I don't Wan 
 use it at all. I searched for a compiler command line 
 disabling for gc but not found. GC.disable() is ugly way I 
 think.
As long as you want to use things like classes and Phobos, you're stuck with the GC being linked in and active at some point in the lifetime of your process. D's runtime includes a lot of infrastructure such as threading that is initialized before your main ever executes. You can limit the GC activity by things like GC.disable, but its still linked in and in use at some point in time. D's GC is your friend, if you don't allocate it won't attempt to collect unless you want it to.
well I know it's my friend, but we're just friend :) I don't want to use it because it's uses alot of heap and I don't like it. my case is special and all of heap usages needs to be done by me. so I want to do something to avoid this dynamic and runtime linkages and etc and be pure and in my hand. definitely it must be some flags or configurations to disable this stuff for a system language. am I right?
I already gave you the solution one message above; betterC (A subset of D) is what you want.
yes sorry, I saw and I was reading about it, thank you. as I found, I can't use some important features in betterC. like classes. but I need them.
Sep 01 2022
next sibling parent reply bauss <jacobbauss gmail.com> writes:
On Thursday, 1 September 2022 at 11:17:20 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 11:06:31 UTC, bauss wrote:
 On Thursday, 1 September 2022 at 10:51:44 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 10:21:32 UTC, rikki 
 cattermole wrote:
 On 01/09/2022 10:13 PM, Redwan wrote:
 if it's for GC, how to completely disable gc? I don't Wan 
 use it at all. I searched for a compiler command line 
 disabling for gc but not found. GC.disable() is ugly way I 
 think.
As long as you want to use things like classes and Phobos, you're stuck with the GC being linked in and active at some point in the lifetime of your process. D's runtime includes a lot of infrastructure such as threading that is initialized before your main ever executes. You can limit the GC activity by things like GC.disable, but its still linked in and in use at some point in time. D's GC is your friend, if you don't allocate it won't attempt to collect unless you want it to.
well I know it's my friend, but we're just friend :) I don't want to use it because it's uses alot of heap and I don't like it. my case is special and all of heap usages needs to be done by me. so I want to do something to avoid this dynamic and runtime linkages and etc and be pure and in my hand. definitely it must be some flags or configurations to disable this stuff for a system language. am I right?
I already gave you the solution one message above; betterC (A subset of D) is what you want.
yes sorry, I saw and I was reading about it, thank you. as I found, I can't use some important features in betterC. like classes. but I need them.
Are you sure you need classes and can't do with structs?
Sep 01 2022
parent reply Redwan <rdwnsjjd gmail.com> writes:
On Thursday, 1 September 2022 at 12:00:40 UTC, bauss wrote:
 On Thursday, 1 September 2022 at 11:17:20 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 11:06:31 UTC, bauss wrote:
 On Thursday, 1 September 2022 at 10:51:44 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 10:21:32 UTC, rikki 
 cattermole wrote:
 On 01/09/2022 10:13 PM, Redwan wrote:
 if it's for GC, how to completely disable gc? I don't Wan 
 use it at all. I searched for a compiler command line 
 disabling for gc but not found. GC.disable() is ugly way I 
 think.
As long as you want to use things like classes and Phobos, you're stuck with the GC being linked in and active at some point in the lifetime of your process. D's runtime includes a lot of infrastructure such as threading that is initialized before your main ever executes. You can limit the GC activity by things like GC.disable, but its still linked in and in use at some point in time. D's GC is your friend, if you don't allocate it won't attempt to collect unless you want it to.
well I know it's my friend, but we're just friend :) I don't want to use it because it's uses alot of heap and I don't like it. my case is special and all of heap usages needs to be done by me. so I want to do something to avoid this dynamic and runtime linkages and etc and be pure and in my hand. definitely it must be some flags or configurations to disable this stuff for a system language. am I right?
I already gave you the solution one message above; betterC (A subset of D) is what you want.
yes sorry, I saw and I was reading about it, thank you. as I found, I can't use some important features in betterC. like classes. but I need them.
Are you sure you need classes and can't do with structs?
I need inheritance and other OOP concepts and template features. does D's struct support them? as I found, No.
Sep 01 2022
next sibling parent Guillaume Piolat <first.last spam.org> writes:
On Thursday, 1 September 2022 at 12:08:05 UTC, Redwan wrote:
 I need inheritance and other OOP concepts and template 
 features. does D's struct support them? as I found, No.
There are ways to put classes on the stack (std.typecons.scoped, emplace()...), but not completely polymorphic classes. In C++, polymorphic dynamic-dispatch objects are not value types either, you need the concrete type to put them on stack or risk slicing. They would typically be on the heap with `new` / `unique_ptr`. So it's really the same constraints, if you have a capped maximum of what the child class will be, you can also emplace in a byte array on the stack any instance of the hiearachy.
Sep 01 2022
prev sibling parent bauss <jacobbauss gmail.com> writes:
On Thursday, 1 September 2022 at 12:08:05 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 12:00:40 UTC, bauss wrote:
 On Thursday, 1 September 2022 at 11:17:20 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 11:06:31 UTC, bauss wrote:
 On Thursday, 1 September 2022 at 10:51:44 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 10:21:32 UTC, rikki 
 cattermole wrote:
 On 01/09/2022 10:13 PM, Redwan wrote:
 if it's for GC, how to completely disable gc? I don't Wan 
 use it at all. I searched for a compiler command line 
 disabling for gc but not found. GC.disable() is ugly way 
 I think.
As long as you want to use things like classes and Phobos, you're stuck with the GC being linked in and active at some point in the lifetime of your process. D's runtime includes a lot of infrastructure such as threading that is initialized before your main ever executes. You can limit the GC activity by things like GC.disable, but its still linked in and in use at some point in time. D's GC is your friend, if you don't allocate it won't attempt to collect unless you want it to.
well I know it's my friend, but we're just friend :) I don't want to use it because it's uses alot of heap and I don't like it. my case is special and all of heap usages needs to be done by me. so I want to do something to avoid this dynamic and runtime linkages and etc and be pure and in my hand. definitely it must be some flags or configurations to disable this stuff for a system language. am I right?
I already gave you the solution one message above; betterC (A subset of D) is what you want.
yes sorry, I saw and I was reading about it, thank you. as I found, I can't use some important features in betterC. like classes. but I need them.
Are you sure you need classes and can't do with structs?
I need inheritance and other OOP concepts and template features. does D's struct support them? as I found, No.
Structs support templates fully, struct S(T) { ... } is supported. Inheritance no, but you can sort of cheat with it using alias this. You can probably achieve what you want without OOP, OOP isn't always the right choice and in most cases people confuse procedural programming with object oriented programming.
Sep 01 2022
prev sibling parent reply Commander Zot <no no.no> writes:
On Thursday, 1 September 2022 at 11:17:20 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 11:06:31 UTC, bauss wrote:
 On Thursday, 1 September 2022 at 10:51:44 UTC, Redwan wrote:
 [...]
I already gave you the solution one message above; betterC (A subset of D) is what you want.
yes sorry, I saw and I was reading about it, thank you. as I found, I can't use some important features in betterC. like classes. but I need them.
as an alternative to betterC, you could write your own runtime.
Sep 01 2022
parent reply Redwan <rdwnsjjd gmail.com> writes:
On Thursday, 1 September 2022 at 12:50:44 UTC, Commander Zot 
wrote:
 On Thursday, 1 September 2022 at 11:17:20 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 11:06:31 UTC, bauss wrote:
 On Thursday, 1 September 2022 at 10:51:44 UTC, Redwan wrote:
 [...]
I already gave you the solution one message above; betterC (A subset of D) is what you want.
yes sorry, I saw and I was reading about it, thank you. as I found, I can't use some important features in betterC. like classes. but I need them.
as an alternative to betterC, you could write your own runtime.
How???
Sep 01 2022
parent rikki cattermole <rikki cattermole.co.nz> writes:
On 02/09/2022 12:53 AM, Redwan wrote:
 as an alternative to betterC, you could write your own runtime.
How???
May be a good starting point: https://github.com/hmmdyl/LWDR
Sep 01 2022
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 9/1/22 03:51, Redwan wrote:

 it's uses alot of heap and I don't like it.
 all of heap usages needs to be done by me
As a fellow ex-C++ programmer (actually, I am still exposed to C++ and I don't like what I see), I know my old feelings of "I don't like it", "I need", and "I want" were remnants of what C++ had convinced me in its way of thinking. Now I know that what matters is one correct and super efficient program written while having fun. I use the GC wherever it makes sense and I use classes where they make sense. By one count, I had 95 structs, 2 classes, and 1 interface in my family of programs. "Everything is a class" has always been wrong. It took me a long time to see through some experts. By the way, I haven't started to use nogc yet. The only time I had a memory leak in D was due to integral values being mistaken for pointers for a 32-bit build when I was loading files into huge buffers. I don't use 32 bits anymore, I don't do that anymore, and D runtime has been improved since then to have some information where actual pointers are. Ali
Sep 01 2022
parent reply Paul Backus <snarwin gmail.com> writes:
On Thursday, 1 September 2022 at 17:24:41 UTC, Ali Çehreli wrote:
 The only time I had a memory leak in D was due to integral 
 values being mistaken for pointers for a 32-bit build when I 
 was loading files into huge buffers. I don't use 32 bits 
 anymore, I don't do that anymore, and D runtime has been 
 improved since then to have some information where actual 
 pointers are.
Recently, we had someone in the community Discord ask for help tracking down a memory leak in their D project, which used the GC. After a bit of investigation, it turned out that the leak was coming from a C library holding onto manually-allocated data longer than expected. In order to free it, the user had to call an additional library function to indicate that the data was no longer needed. Moral of the story: if you are worried about memory leaks, the GC is your friend, not your enemy. :)
Sep 01 2022
parent Walter Bright <newshound2 digitalmars.com> writes:
On 9/1/2022 10:50 AM, Paul Backus wrote:
 Recently, we had someone in the community Discord ask for help tracking down a 
 memory leak in their D project, which used the GC.
The -profile=gc can be used to track GC allocations.
Sep 01 2022
prev sibling parent reply Redwan <rdwnsjjd gmail.com> writes:
On Thursday, 1 September 2022 at 10:21:32 UTC, rikki cattermole 
wrote:
 On 01/09/2022 10:13 PM, Redwan wrote:
 if it's for GC, how to completely disable gc? I don't Wan use 
 it at all. I searched for a compiler command line disabling 
 for gc but not found. GC.disable() is ugly way I think.
As long as you want to use things like classes and Phobos, you're stuck with the GC being linked in and active at some point in the lifetime of your process. D's runtime includes a lot of infrastructure such as threading that is initialized before your main ever executes. You can limit the GC activity by things like GC.disable, but its still linked in and in use at some point in time. D's GC is your friend, if you don't allocate it won't attempt to collect unless you want it to.
the worst things about it is as I didn't start writing my code it already has memory leak :/
Sep 01 2022
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 01/09/2022 11:20 PM, Redwan wrote:
 the worst things about it is as I didn't start writing my code it 
 already has memory leak :/
That's not what valgrind told you. There is some state like the GC and threads that won't be deallocated until the end of process by the kernel. Its not a memory leak, it is just long lived internal state.
Sep 01 2022
parent reply Redwan <rdwnsjjd gmail.com> writes:
On Thursday, 1 September 2022 at 11:24:38 UTC, rikki cattermole 
wrote:
 On 01/09/2022 11:20 PM, Redwan wrote:
 the worst things about it is as I didn't start writing my code 
 it already has memory leak :/
That's not what valgrind told you. There is some state like the GC and threads that won't be deallocated until the end of process by the kernel. Its not a memory leak, it is just long lived internal state.
so with this state, how can I found memory leak in my program?
Sep 01 2022
parent rikki cattermole <rikki cattermole.co.nz> writes:
On 01/09/2022 11:25 PM, Redwan wrote:
 so with this state, how can I found memory leak in my program?
Most people don't bother beyond valgrind in D. Either its on the stack, GC allocated or reference counted for most people in D. These three strategies pretty much guarantee no leaks (reference counting does have some pitfalls relating to data structures but we can safely ignore that here).
Sep 01 2022
prev sibling next sibling parent bauss <jacobbauss gmail.com> writes:
On Thursday, 1 September 2022 at 10:13:17 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 09:53:08 UTC, Dennis wrote:
 On Thursday, 1 September 2022 at 09:43:55 UTC, Redwan wrote:
 oh, thank you. with this, no allocation??
No heap allocation. The ` nogc` attribute is enforced by the compiler, so you will get an error if you use `new` without `scope` here.
OK tnx. another problem that probably is related to this issue. I compiled this worthless code: ``` void main() {} ``` also this one: ``` nogc void main() {} ``` the valgrind result: ``` ... total heap usage: 143 alloc, 141 frees, 13,236 bytes allocated ... ``` !!! what's this means?? from where comes this allocations and also leaks??? if it's for GC, how to completely disable gc? I don't Wan use it at all. I searched for a compiler command line disabling for gc but not found. GC.disable() is ugly way I think.
Use betterC if you want to avoid the D runtime.
Sep 01 2022
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 9/1/22 6:13 AM, Redwan wrote:
 On Thursday, 1 September 2022 at 09:53:08 UTC, Dennis wrote:
 On Thursday, 1 September 2022 at 09:43:55 UTC, Redwan wrote:
 oh, thank you. with this, no allocation??
No heap allocation. The ` nogc` attribute is enforced by the compiler, so you will get an error if you use `new` without `scope` here.
OK tnx. another problem that probably is related to this issue. I compiled this worthless code: ``` void main() {} ``` also this one: ``` nogc void main() {} ``` the valgrind result: ``` ... total heap usage: 143 alloc, 141 frees, 13,236 bytes allocated ... ``` !!! what's this means?? from where comes this allocations and also leaks???
The runtime does some allocations before running main. But these are all C malloc allocations and not GC allocations. There should be zero GC usage in these programs. As for "leaks", I think it would tell you that. Looking on the internet, this may count for "reachable" data, that is, data that is allocated, and still referenced at program exit. Such memory is not a "leak" in the sense that you just stopped pointing at it and never freed it. I suggest you look at the remaining valgrind outputs. This is what I got: ``` $ valgrind --leak-check=full --show-leak-kinds=all ./testmemleak ==418523== Memcheck, a memory error detector ==418523== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==418523== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info ==418523== Command: ./testmemleak ==418523== ==418523== ==418523== HEAP SUMMARY: ==418523== in use at exit: 96 bytes in 2 blocks ==418523== total heap usage: 149 allocs, 147 frees, 14,896 bytes allocated ==418523== ==418523== 24 bytes in 1 blocks are still reachable in loss record 1 of 2 ==418523== at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==418523== by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==418523== by 0x14E10D: _D4core8internal9container6common8xreallocFNbNiPvmZQe (in /home/steves/testmemleak) ==418523== by 0x15C095: _D4core8internal2gc4impl5protoQo7ProtoGC8addRangeMFNbNiPvmxC8TypeInfoZv (in /home/steves/testmemleak) ==418523== by 0x14E3FF: gc_addRange (in /home/steves/testmemleak) ==418523== by 0x150275: _D2rt6memory16initStaticDataGCFZ14__foreachbody1MFNbNiKSQCc19secti ns_elf_shared3DSOZi (in /home/steves/testmemleak) ==418523== by 0x152657: _D2rt19sections_elf_shared3DSO7opApplyFMDFKSQBqQBqQyZiZi (in /home/steves/testmemleak) ==418523== by 0x150218: _D2rt6memory16initStaticDataGCFZv (in /home/steves/testmemleak) ==418523== by 0x14ECF8: rt_init (in /home/steves/testmemleak) ==418523== by 0x14BB27: _D2rt6dmain212_d_run_main2UAAamPUQgZiZ6runAllMFZv (in /home/steves/testmemleak) ==418523== by 0x14BAC5: _D2rt6dmain212_d_run_main2UAAamPUQgZiZ7tryExecMFMDFZvZv (in /home/steves/testmemleak) ==418523== by 0x14BA2E: _d_run_main2 (in /home/steves/testmemleak) ==418523== ==418523== 72 bytes in 1 blocks are still reachable in loss record 2 of 2 ==418523== at 0x483DFAF: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==418523== by 0x17C0E1: _d_register_manual_gc (in /home/steves/testmemleak) ==418523== by 0x18455C: __libc_csu_init (in /home/steves/testmemleak) ==418523== by 0x48B703F: (below main) (libc-start.c:264) ==418523== ==418523== LEAK SUMMARY: ==418523== definitely lost: 0 bytes in 0 blocks ==418523== indirectly lost: 0 bytes in 0 blocks ==418523== possibly lost: 0 bytes in 0 blocks ==418523== still reachable: 96 bytes in 2 blocks ==418523== suppressed: 0 bytes in 0 blocks ==418523== ==418523== For lists of detected and suppressed errors, rerun with: -s ==418523== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ``` The 72 bytes allocated was to register the manual GC, which is run before even C's main runs. The 24 bytes was allocated to add a range in the runtime initialization. It looks like it's this line: https://github.com/dlang/dmd/blob/09d04945bdbc0cba36f7bb1e19d5bd009d4b0ff2/druntime/src/rt/memory.d#L24 Note, however, that prior to the GC being used to actually allocate anything, it's *not* initialized. Instead it is a specialized object that will just malloc this range until the real GC is set up. It's not a leak because it's still in use when the program exits. -Steve
Sep 01 2022
parent reply Johan <j j.nl> writes:
On Thursday, 1 September 2022 at 13:23:42 UTC, Steven 
Schveighoffer wrote:
 On 9/1/22 6:13 AM, Redwan wrote:
 
 OK tnx. another problem that probably is related to this issue.
 I compiled this worthless code:
 ```
 void main() {}
 ```
 
 also this one:
 ```
  nogc void main() {}
 ```
 
 
 the valgrind result:
 ```
 ...
 total heap usage: 143 alloc, 141 frees, 13,236 bytes allocated
 ...
 ```
 
 !!!
 what's this means??
 from where comes this allocations and also leaks???
The runtime does some allocations before running main. But these are all C malloc allocations and not GC allocations. There should be zero GC usage in these programs.
Hi Steven, I think you would agree that one hundred and forty three allocations (=malloc calls?) is a very large (unacceptable) amount for just starting and shutting down the runtime of D.
 As for "leaks", I think it would tell you that. Looking on the 
 internet, this may count for "reachable" data, that is, data 
 that is allocated, and still referenced at program exit. Such 
 memory is not a "leak" in the sense that you just stopped 
 pointing at it and never freed it.
Matching deallocations should also be required of a language runtime. Every user is forced to use the druntime, it is not an optional component (yes -betterC, come on). One example mentioned on StackOverflow is the case of a DLL [1]. regards, Johan [1] https://stackoverflow.com/questions/3840582/still-reachable-leak-detected-by-valgrind#comment90930092_3857638
Sep 01 2022
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 9/1/22 4:11 PM, Johan wrote:
 On Thursday, 1 September 2022 at 13:23:42 UTC, Steven Schveighoffer wrote:
 On 9/1/22 6:13 AM, Redwan wrote:
 OK tnx. another problem that probably is related to this issue.
 I compiled this worthless code:
 ```
 void main() {}
 ```

 also this one:
 ```
  nogc void main() {}
 ```


 the valgrind result:
 ```
 ...
 total heap usage: 143 alloc, 141 frees, 13,236 bytes allocated
 ...
 ```

 !!!
 what's this means??
 from where comes this allocations and also leaks???
The runtime does some allocations before running main. But these are all C malloc allocations and not GC allocations. There should be zero GC usage in these programs.
Hi Steven,   I think you would agree that one hundred and forty three allocations (=malloc calls?) is a very large (unacceptable) amount for just starting and shutting down the runtime of D.
I think it's malloc and realloc. No I don't think that is too much. How much would be acceptable for you? One thing I can think of that I was personally involved with that does allocations is the module sorting algorithm (used for detecting cycles and proper ordering of module ctor/dtor). This allocates and deallocate temporary structures to do the directed graph sorting. 143 seems like quite a lot for that, I would still be interested to see what all the *exact* allocations are. It also probably allocates the string array for the main args.
 
 As for "leaks", I think it would tell you that. Looking on the 
 internet, this may count for "reachable" data, that is, data that is 
 allocated, and still referenced at program exit. Such memory is not a 
 "leak" in the sense that you just stopped pointing at it and never 
 freed it.
Matching deallocations should also be required of a language runtime. Every user is forced to use the druntime, it is not an optional component (yes -betterC, come on). One example mentioned on StackOverflow is the case of a DLL [1].
The allocation done by rt_init should be deallocated by rt_term, and clearly it's not. If there is not a bug report on that, there should be. The ones done by pragma(crt_constructor) I don't know how that works in terms of having dlls. So maybe that one is OK. On a somewhat related note, I wish that there would be a way to avoid the module constructor sorting at runtime, because it is the same every time, and a waste of CPU cycles to do it. But this can only be done *after* linking. If there were some way to preallocate space for the module ctor cycle order, and then run a post-build step to edit that graph, it would be a great improvement to have. -Steve
Sep 01 2022
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 9/1/2022 4:58 PM, Steven Schveighoffer wrote:
 On a somewhat related note, I wish that there would be a way to avoid the
module 
 constructor sorting at runtime, because it is the same every time, and a waste 
 of CPU cycles to do it. But this can only be done *after* linking. If there
were 
 some way to preallocate space for the module ctor cycle order, and then run a 
 post-build step to edit that graph, it would be a great improvement to have.
How many modules are in your program?
Sep 01 2022
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 9/2/22 12:23 AM, Walter Bright wrote:
 On 9/1/2022 4:58 PM, Steven Schveighoffer wrote:
 On a somewhat related note, I wish that there would be a way to avoid 
 the module constructor sorting at runtime, because it is the same 
 every time, and a waste of CPU cycles to do it. But this can only be 
 done *after* linking. If there were some way to preallocate space for 
 the module ctor cycle order, and then run a post-build step to edit 
 that graph, it would be a great improvement to have.
How many modules are in your program?
What do you mean? If you are suggesting that probably the module sorting is insignificant, it definitely is not very intensive. What I don't like about it is that it is a sort of immutable data. In other words, the data does not change from one run to the next, but it's stored unordered, and then every time the program loads, we have to order it. Every time a DLL is loaded, this algorithm needs to be run. It would be nice if it were stored in the order needed, so no sorting is needed. The sorting algorithm is complex as well, it's not a simple quicksort. -Steve
Sep 02 2022
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 9/2/2022 6:23 AM, Steven Schveighoffer wrote:
 What do you mean? If you are suggesting that probably the module sorting is 
 insignificant, it definitely is not very intensive.
I am indeed suggesting it is insignificant.
 What I don't like about it is that it is a sort of immutable data. In other 
 words, the data does not change from one run to the next, but it's stored 
 unordered, and then every time the program loads, we have to order it. Every 
 time a DLL is loaded, this algorithm needs to be run.
 
 It would be nice if it were stored in the order needed, so no sorting is
needed. 
 The sorting algorithm is complex as well, it's not a simple quicksort.
In the olden days, I (and others) would just have the executable self-patch itself. But such behavior was then banned by the OS.
Sep 02 2022
next sibling parent IGotD- <nise nise.com> writes:
On Friday, 2 September 2022 at 19:54:44 UTC, Walter Bright wrote:
 On 9/2/2022 6:23 AM, Steven Schveighoffer wrote:
 What do you mean? If you are suggesting that probably the 
 module sorting is insignificant, it definitely is not very 
 intensive.
I am indeed suggesting it is insignificant.
If this can be done at compile time, there is no reason why it shouldn't. This is another task that should be done in D3.
Sep 05 2022
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 9/2/22 3:54 PM, Walter Bright wrote:
 On 9/2/2022 6:23 AM, Steven Schveighoffer wrote:
 What do you mean? If you are suggesting that probably the module 
 sorting is insignificant, it definitely is not very intensive.
I am indeed suggesting it is insignificant.
I'd hazard to guess it's indistinguishable really. Probably on the order of a couple milliseconds, even on a large module set. It's not so much the performance, but the principle, and also the requirement of code to do something that is knowable really at link-time.
 
 In the olden days, I (and others) would just have the executable 
 self-patch itself. But such behavior was then banned by the OS.
 
I'm thinking more about either an intermediate step to the linker (once all objects are known), or a post-link step. Not something that happens at runtime. What *could* happen is some --DRT switch to output the correct sorting, and then another tool that takes that as input, and can then properly edit the executable, or provide a specialized file to the compiler so it spits out a pre-organized module list. Can they be weak symbols, and then you just link the object file with that data ahead of everything else? Or, just the rt_init function could be told "use this pointer array as the list instead of the sorting." Actually, I think that last idea is doable without any compiler changes... I'll have to investigate. -Steve
Sep 05 2022
prev sibling parent reply IGotD- <nise nise.com> writes:
On Thursday, 1 September 2022 at 09:43:55 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 09:40:06 UTC, Dennis wrote:
 On Thursday, 1 September 2022 at 09:13:56 UTC, Redwan wrote:
 I want declare classes and create instance of them on stack 
 and nicely use them.
You can use that using the `scope` storage class on a local variable with a class type: https://dlang.org/spec/attribute.html#scope-class-var ```D void main() nogc { scope o = new Object(); } ``` The ` nogc` attribute ensures no allocations are made with the Garbage Collector.
oh, thank you. with this, no allocation??
If you have any classes in the class you allocate on the stack, the constructor of the class will allocate them on the heap. Basically only the top level class will be on stack.
Sep 01 2022
parent reply Redwan <rdwnsjjd gmail.com> writes:
On Thursday, 1 September 2022 at 13:53:06 UTC, IGotD- wrote:
 On Thursday, 1 September 2022 at 09:43:55 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 09:40:06 UTC, Dennis wrote:
 On Thursday, 1 September 2022 at 09:13:56 UTC, Redwan wrote:
 [...]
You can use that using the `scope` storage class on a local variable with a class type: https://dlang.org/spec/attribute.html#scope-class-var ```D void main() nogc { scope o = new Object(); } ``` The ` nogc` attribute ensures no allocations are made with the Garbage Collector.
oh, thank you. with this, no allocation??
If you have any classes in the class you allocate on the stack, the constructor of the class will allocate them on the heap. Basically only the top level class will be on stack.
Can you give an example?
Sep 01 2022
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 9/1/22 10:59, Redwan wrote:
 On Thursday, 1 September 2022 at 13:53:06 UTC, IGotD- wrote:
 If you have any classes in the class you allocate on the stack, the 
 constructor of the class will allocate them on the heap. Basically 
 only the top level class will be on stack.
Can you give an example?
Sorry to jump in but the following program demonstrates this by pointer values: import std.stdio; class A { int i; } class B { A a; int i; this() { this.a = new A(); } } void main() { scope b = new B(); int i; writeln("on stack: ", &i); writeln("on stack: ", &b.i); writeln("on heap : ", &b.a.i); } Ali
Sep 01 2022
parent reply Redwan <rdwnsjjd gmail.com> writes:
On Thursday, 1 September 2022 at 18:26:12 UTC, Ali Çehreli wrote:
 On 9/1/22 10:59, Redwan wrote:
 On Thursday, 1 September 2022 at 13:53:06 UTC, IGotD- wrote:
 If you have any classes in the class you allocate on the 
 stack, the constructor of the class will allocate them on the 
 heap. Basically only the top level class will be on stack.
Can you give an example?
Sorry to jump in but the following program demonstrates this by pointer values: import std.stdio; class A { int i; } class B { A a; int i; this() { this.a = new A(); } } void main() { scope b = new B(); int i; writeln("on stack: ", &i); writeln("on stack: ", &b.i); writeln("on heap : ", &b.a.i); } Ali
how about `scope this.a = new A();`?
Sep 01 2022
next sibling parent mw <mingwu gmail.com> writes:
On Thursday, 1 September 2022 at 18:50:05 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 18:26:12 UTC, Ali Çehreli 
 wrote:
 On 9/1/22 10:59, Redwan wrote:
 On Thursday, 1 September 2022 at 13:53:06 UTC, IGotD- wrote:
 If you have any classes in the class you allocate on the 
 stack, the constructor of the class will allocate them on 
 the heap. Basically only the top level class will be on 
 stack.
Can you give an example?
Sorry to jump in but the following program demonstrates this by pointer values: import std.stdio; class A { int i; } class B { A a; int i; this() { this.a = new A(); } } void main() { scope b = new B(); int i; writeln("on stack: ", &i); writeln("on stack: ", &b.i); writeln("on heap : ", &b.a.i); } Ali
how about `scope this.a = new A();`?
It won't compile: onlineapp.d(21): Error: found `=` instead of statement try it online here: https://run.dlang.io/
Sep 01 2022
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Thursday, 1 September 2022 at 18:50:05 UTC, Redwan wrote:
 On Thursday, 1 September 2022 at 18:26:12 UTC, Ali Çehreli 
 wrote:
 import std.stdio;

 class A {
   int i;
 }

 class B {
   A a;
   int i;

   this() {
     this.a = new A();
   }
 }

 void main() {
   scope b = new B();
   int i;

   writeln("on stack: ", &i);
   writeln("on stack: ", &b.i);
   writeln("on heap : ", &b.a.i);
 }

 Ali
how about `scope this.a = new A();`?
If you want everything on the stack, you have to pass in `a` as an argument, like this: class A {} class B { A a; this(A a) { this.a = a; } } void main() { scope a = new A(); // on stack scope b = new B(a); // on stack }
Sep 01 2022
parent reply IGotD- <nise nise.com> writes:
On Thursday, 1 September 2022 at 19:27:13 UTC, Paul Backus wrote:
 If you want everything on the stack, you have to pass in `a` as 
 an argument, like this:

 class A {}

 class B {
   A a;

   this(A a) {
     this.a = a;
   }
 }

 void main() {
   scope a = new A(); // on stack
   scope b = new B(a); // on stack
 }
I previously saw an example that allocated the space in the class for the member class, unfortunately I cannot find it. Then it runs emplace in order to run the constructor. This way you don't need to allocate it outside the top level stack, which is annoying when you have many of them.
Sep 01 2022
next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 9/1/22 12:45, IGotD- wrote:

 an example that allocated the space in the class for
 the member class
I am experimenting with a similar idea where the user can ask a type to have a buffer as a member: struct S(T, size_t memberCapacity = size_t.max) { static if (memberCapacity != size_t.max) { // The user wants a member array T[memberCapacity] arr; void initMemberArray() { // Real work with 'arr'... } } else { void initMemberArray() { // No work needed in this case } } // ... } void main() { auto a = S!int(); auto b = S!(int, 42)(); pragma(msg, a.sizeof); // 1 pragma(msg, b.sizeof); // 168 } Ali
Sep 01 2022
prev sibling parent Nick Treleaven <nick geany.org> writes:
On Thursday, 1 September 2022 at 19:45:08 UTC, IGotD- wrote:
 I previously saw an example that allocated the space in the 
 class for the member class, unfortunately I cannot find it.
There's scoped: https://dlang.org/library/std/typecons/scoped.html Scroll down the example to the "Use as member variable" part. I assume it can be used as a class member too.
Sep 03 2022
prev sibling next sibling parent IGotD- <nise nise.com> writes:
On Thursday, 1 September 2022 at 09:13:56 UTC, Redwan wrote:
 Hi all
 I'm new to D from c, cpp and Rust.

 this language made me surprised because of its features and 
 syntax and etc.

 but I shocked when I found that classes must be created only on 
 stack! Is this nightmare real? why???
 I want declare classes and create instance of them on stack and 
 nicely use them. why I must put them on heap??
 structs does not support inheritance and I don't want to use 
 them. please tell me that is not true or give me some other 
 ways. I don't want define objects always on heap. don't let me 
 go back on cpp :( tnx!
This comes from the 90s old classes are reference type and have been discussed previously in this forum and I have seen kind of vague answer about it. However, you can allocate a class on the stack using the scoped template. One more serious flaw to this is that classes are not expanded as members in the host class, which means that memory allocation and fragmentation is much worse than people think. It is possible to expand member classes into host classes using some kind of hack though. For "multiple" inheritance, use composition with mixins which I assume you are after. Basically, I don't buy why why classes must be reference types and must be allocated on the heap. I have not seen a good explanation to this, or I have not fully understood it.
Sep 01 2022
prev sibling parent dd <dd dax.moe> writes:
On Thursday, 1 September 2022 at 09:13:56 UTC, Redwan wrote:
 Hi all
 I'm new to D from c, cpp and Rust.

 this language made me surprised because of its features and 
 syntax and etc.

 but I shocked when I found that classes must be created only on 
 stack! Is this nightmare real? why???
 I want declare classes and create instance of them on stack and 
 nicely use them. why I must put them on heap??
 structs does not support inheritance and I don't want to use 
 them. please tell me that is not true or give me some other 
 ways. I don't want define objects always on heap. don't let me 
 go back on cpp :( tnx!
I think something like std.typecons.scoped (https://dlang.org/phobos/std_typecons.html#scoped) does something like this, I think.
Sep 01 2022