Jump to page: 1 2
Thread overview
anonymous functions and scope(exit)
Jul 03, 2021
Luis
Jul 03, 2021
frame
Jul 03, 2021
frame
Jul 03, 2021
Luis
Jul 03, 2021
frame
Jul 04, 2021
Luis
Jul 04, 2021
jfondren
Jul 04, 2021
jfondren
Jul 04, 2021
Luis
Jul 04, 2021
frame
Jul 03, 2021
jfondren
Jul 03, 2021
Dennis
Jul 03, 2021
Luis
July 03, 2021

This is intentional ?

        should(function void() {
            auto emptyStack = SimpleStack!int();
            scope(exit) emptyStack.free; // <= This is never called

            emptyStack.reserve(16);
            emptyStack.top;
        }).Throw!RangeError;

scope(exit) inside of a anonymous functions, it's never called.

July 03, 2021

On Saturday, 3 July 2021 at 17:20:47 UTC, Luis wrote:

>

This is intentional ?

        should(function void() {
            auto emptyStack = SimpleStack!int();
            scope(exit) emptyStack.free; // <= This is never called

            emptyStack.reserve(16);
            emptyStack.top;
        }).Throw!RangeError;

scope(exit) inside of a anonymous functions, it's never called.

Please provide an example code. What lib is this? Normally scope(exit) works also for anonymous functions.

July 03, 2021

On 7/3/21 1:20 PM, Luis wrote:

>

This is intentional ?

         should(function void() {
             auto emptyStack = SimpleStack!int();
             scope(exit) emptyStack.free; // <= This is never called

             emptyStack.reserve(16);
             emptyStack.top;
         }).Throw!RangeError;

scope(exit) inside of a anonymous functions, it's never called.

In principle, it should technically be called.

But in practice, the compiler does not have to clean up anything when an Error is thrown. Whether it does or not is defined by the implementation.

However, it should always work if it's an Exception and not an Error.


import std.stdio;

void main()
{
    auto f = function void() {
        scope(exit) writeln("hi");
        throw new Exception("boo");
    };

    f();
}

prints "hi"

-Steve

July 03, 2021

On Saturday, 3 July 2021 at 17:20:47 UTC, Luis wrote:

>

This is intentional ?
...
scope(exit) inside of a anonymous functions, it's never called.

$ rdmd --eval 'iota(2).map!((int x) { scope(exit) writeln("got: ", x); return x+1; }).array.writeln'
got: 0
got: 1
[1, 2]

Conclusion: it's not intentional.

July 03, 2021

On Saturday, 3 July 2021 at 17:20:47 UTC, Luis wrote:

>

scope(exit) inside of a anonymous functions, it's never called.

I think the compiler infers the function nothrow since you don't throw any Exception, only an Error. Errors represent unrecoverable bugs, after which the program is in an invalid state, so the compiler is free to exit immediately without caring about destructors or scope(exit). Use Exception instead of Error if you want the stack to properly unwind.

July 03, 2021

On Saturday, 3 July 2021 at 17:39:18 UTC, Steven Schveighoffer wrote:

>

But in practice, the compiler does not have to clean up anything when an Error is thrown. Whether it does or not is defined by the implementation.

This should be really mentionend in the docs? "Guard", yeah...

July 03, 2021

On 7/3/21 4:08 PM, frame wrote:

>

On Saturday, 3 July 2021 at 17:39:18 UTC, Steven Schveighoffer wrote:

>

But in practice, the compiler does not have to clean up anything when an Error is thrown. Whether it does or not is defined by the implementation.

This should be really mentionend in the docs? "Guard", yeah...

Yeah, there isn't a good discussion of the differences between Error and Exception on that page.

-Steve

July 03, 2021

On Saturday, 3 July 2021 at 17:47:47 UTC, Dennis wrote:

>

On Saturday, 3 July 2021 at 17:20:47 UTC, Luis wrote:

>

scope(exit) inside of a anonymous functions, it's never called.

I think the compiler infers the function nothrow since you don't throw any Exception, only an Error. Errors represent unrecoverable bugs, after which the program is in an invalid state, so the compiler is free to exit immediately without caring about destructors or scope(exit). Use Exception instead of Error if you want the stack to properly unwind.

Indeed, this is happening.

I can reproduce with this :

#!/usr/bin/env dub
/+ dub.sdl:
  dependency "pijamas" version="~>1.1"
+/
import core.exception;

void main()  {
  import core.stdc.stdio;
  import pijamas;

  should(() {
    printf("Hello\n");
    scope(exit) printf("Bye\n");
    throw new RangeError("bla bla");
  }).Throw!RangeError;

  auto f = () {
      printf("Hello\n");
      scope(exit) printf("Bye\n");
      throw new RangeError("bla bla");
    };
  f();
}

Outputs this :

$ f.d
Hello
Hello
core.exception.RangeError@bla bla(20): Range violation
----------------
source/f.d:20 nothrow void f.main().__lambda2() [0x5647d46a17db]
source/f.d:22 _Dmain [0x5647d46a1732]
Program exited with code 1

If I change the RangeError, by a Exception, then the scope(exit) it's executed.

July 03, 2021

On Saturday, 3 July 2021 at 20:46:00 UTC, Steven Schveighoffer wrote:

>

On 7/3/21 4:08 PM, frame wrote:

>

On Saturday, 3 July 2021 at 17:39:18 UTC, Steven Schveighoffer wrote:

>

But in practice, the compiler does not have to clean up anything when an Error is thrown. Whether it does or not is defined by the implementation.

This should be really mentionend in the docs? "Guard", yeah...

Yeah, there isn't a good discussion of the differences between Error and Exception on that page.

-Steve

On The D Error Handling Solution, says :

>

If code detects an error like "out of memory," then an Error is thrown with a message
saying "Out of memory". The function call stack is unwound, looking for a handler for
the Error. Finally blocks are executed as the stack is unwound. If an error handler is
found, execution resumes there. If not, the default Error handler is run, which displays
the message and terminates the program.

scope(exit) it's syntactic sugar for a classic try {} finally {} . The documentation says that must be executed.

July 03, 2021

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.

« First   ‹ Prev
1 2