September 01, 2022
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.
September 01, 2022
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???
September 02, 2022
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
September 01, 2022

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__foreachbody1MFNbNiKSQCc19sections_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

September 01, 2022

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

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.

September 01, 2022
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

September 01, 2022
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. :)
September 01, 2022

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

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?

September 01, 2022
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
September 01, 2022
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();`?