anonymous functions and scope(exit)

Luis Luis.panadero at gmail.com
Sun Jul 4 08:24:36 UTC 2021


On Saturday, 3 July 2021 at 22:52:39 UTC, frame wrote:
> On Saturday, 3 July 2021 at 22:04:04 UTC, Luis wrote:
>
>> scope(exit) it's syntactic sugar for a classic `try {} finally 
>> {}` . The documentation says that must be executed.
>
> It works if you replace printf() with writeln() or use 
> writeln() after. There must be some buffer issue.

Not works as you expected.
Yes, replacing by writeln (better said, putting a writeln) makes 
it to work. More weird, if I replace the printf(...) by a 
fprintf(stderr, ...), I don't get anything.

To discard depening on checking if it works by the side effect of 
writing something on the console, now i using malloc/free and 
checking with valgrind for a lost memory :

```d
#!/usr/bin/env dub
/+ dub.sdl:
   dependency "pijamas" version="~>1.1"
+/
import core.exception;
import core.stdc.stdio;
import core.stdc.stdlib;
import std.stdio : writeln;


void main()  {
   import pijamas;

   should(() {
     int* ptr = cast(int*) malloc(int.sizeof * 1000);
     try {
       fprintf(stderr, "Hello\n");
       throw new RangeError("bla bla");
     } finally {
       // writeln("Bye 1");
       fprintf(stderr, "Bye\n");
       free(ptr);
     }
   }).Throw!RangeError;
}

```

Outputs this :
```
$ f.d
Hello
```

And valgrind outputs (using the temporal executable generated by 
dub on /tmp/.dub/...) :

```
$ valgrind --leak-check=full 
/tmp/.dub/build/f-\~master/application-debug-linux.posix-x86_64-dmd_2097-FB7AFBA927D99FA3DDD7307BACA865DA/f
==18356== Memcheck, a memory error detector
==18356== Copyright (C) 2002-2017, and GNU GPL'd, by Julian 
Seward et al.
==18356== Using Valgrind-3.15.0 and LibVEX; rerun with -h for 
copyright info
==18356== Command: 
/tmp/.dub/build/f-~master/application-debug-linux.posix-x86_64-dmd_2097-FB7AFBA927D99FA3DDD7307BACA865DA/f
==18356==
--18356-- WARNING: Serious error when reading debug info
--18356-- When reading debug info from 
/tmp/.dub/build/f-~master/application-debug-linux.posix-x86_64-dmd_2097-FB7AFBA927D99FA3DDD7307BACA865DA/f:
--18356-- DWARF line info appears to be corrupt - the section is 
too small
--18356-- WARNING: Serious error when reading debug info
--18356-- When reading debug info from 
/tmp/.dub/build/f-~master/application-debug-linux.posix-x86_64-dmd_2097-FB7AFBA927D99FA3DDD7307BACA865DA/f:
--18356-- read_filename_table: .debug_line is missing?
Hello
==18356==
==18356== HEAP SUMMARY:
==18356==     in use at exit: 4,056 bytes in 3 blocks
==18356==   total heap usage: 231 allocs, 228 frees, 76,436 bytes 
allocated
==18356==
==18356== 32 bytes in 1 blocks are possibly lost in loss record 2 
of 3
==18356==    at 0x483B7F3: malloc (in 
/usr/lib/x86_64-linux-gnu/valgrind
....
==18356== 4,000 bytes in 1 blocks are definitely lost in loss 
record 3 of 3
==18356==    at 0x483B7F3: malloc (in 
/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==18356==    by 0x16873D: _D1f4mainFZ9__lambda1FNbZv (f.d:15)
==18356==    by 0x168B2F: 
_D7pijamas9assertion__T9AssertionTPFNbZvZQs__T5ThrowHTC4core9exception10RangeErrorZQBlMFNeAyamZv (assertion.d:602)
==18356==    by 0x168724: _Dmain (assertion.d:598)
==18356==    by 0x18C962: 
_D2rt6dmain212_d_run_main2UAAamPUQgZiZ6runAllMFZ9__lambda2MFZv 
(in 
/tmp/.dub/build/f-~master/application-debug-linux.posix-x86_64-dmd_2097-FB7AFBA927D99FA3DDD7307BACA865DA/f)
==18356==    by 0x18C804: 
_D2rt6dmain212_d_run_main2UAAamPUQgZiZ7tryExecMFMDFZvZv (in 
/tmp/.dub/build/f-~master/application-debug-linux.posix-x86_64-dmd_2097-FB7AFBA927D99FA3DDD7307BACA865DA/f)
==18356==    by 0x18C8DE: 
_D2rt6dmain212_d_run_main2UAAamPUQgZiZ6runAllMFZv (in 
/tmp/.dub/build/f-~master/application-debug-linux.posix-x86_64-dmd_2097-FB7AFBA927D99FA3DDD7307BACA865DA/f)
==18356==    by 0x18C804: 
_D2rt6dmain212_d_run_main2UAAamPUQgZiZ7tryExecMFMDFZvZv (in 
/tmp/.dub/build/f-~master/application-debug-linux.posix-x86_64-dmd_2097-FB7AFBA927D99FA3DDD7307BACA865DA/f)
==18356==    by 0x18C765: _d_run_main2 (in 
/tmp/.dub/build/f-~master/application-debug-linux.posix-x86_64-dmd_2097-FB7AFBA927D99FA3DDD7307BACA865DA/f)
==18356==    by 0x18C4C1: _d_run_main (in 
/tmp/.dub/build/f-~master/application-debug-linux.posix-x86_64-dmd_2097-FB7AFBA927D99FA3DDD7307BACA865DA/f)
==18356==    by 0x1687B9: main (entrypoint.d:29)
==18356==
==18356== LEAK SUMMARY:
==18356==    definitely lost: 4,000 bytes in 1 blocks
==18356==    indirectly lost: 0 bytes in 0 blocks
==18356==      possibly lost: 32 bytes in 1 blocks
==18356==    still reachable: 24 bytes in 1 blocks
==18356==         suppressed: 0 bytes in 0 blocks
==18356== Reachable blocks (those to which a pointer was found) 
are not shown.
==18356== To see them, rerun with: --leak-check=full 
--show-leak-kinds=all
==18356==
==18356== For lists of detected and suppressed errors, rerun 
with: -s
==18356== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 
from 0)
```

But the most funny thing, it's that if I remove the comment on 
the writeln, then just works and the memory leak dissapers! **DMD 
, it's doing very weird things here**, only executing the scope 
(exit) {} / finally {} when there is a side effect with writeln !
**This not happens with my local install of ldc2**.

On my original post, I was just searching for a memory leak on a 
tests of my private library, where I have some @nogc containers 
using std.experimental.allocator, and expecting that the scope 
(exit) being executed and releasing the allocated memory. And 
this wasn't happening.

dmd --version :
DMD64 D Compiler v2.097.0

ldc2 -v :
binary    /usr/bin/ldc2
version   1.20.1 (DMD v2.090.1, LLVM 10.0.0)
config    /etc/ldc2.conf (x86_64-pc-linux-gnu)


More information about the Digitalmars-d-learn mailing list