On Tuesday, 5 June 2018 at 09:03:03 UTC, Simen Kjærås wrote:
On Tuesday, 5 June 2018 at 08:26:22 UTC, Nicholas Wilson wrote:
writeln("Assert"); // this is not caught because the thrown throwable is not an exception

Now that's plain false - If you replace the call to throwingFunc() with a string literal, you'll see it's properly caught. Also, the catch clause explicitly specifies AssertError, which as the name implies, is an Error, not an Exception.


Whoops I meant _is_.

However, if we add catch (Throwable ex) to the list of catch statements, that *does* catch a regular object.Exception. Moving the catch (Exception) statement down the list does nothing. Adding another layer of try-catch also catches it (even with just catch (Exception ex)):

That does seem odd but is consistent with the implicit "try" surrounding Dmain inserted by the runtime.

import std.stdio;
import core.exception;

unittest {
    scope(failure) {
        writeln("Not gonna happen");
    }

    try {
        try {
            static string throwingFunc() {
                throw new Exception("An exception");
            }
            assert(0==1, throwingFunc());
        } catch(AssertError ex) {
            writeln("Assert");
        } catch(Exception ex) {
            writeln("Exception A");
        }
    } catch(Exception ex) {
        writeln("Exception B");
    }
}

So I'm stumped. It seems the exception handling is simply not setup correctly. This could be because of UB I guess, but I'd hope the AssertError would be thrown first in such a case.

The assert error will never be thrown because one of the parameters to the __assert_fail throws. Its like as if you had written.

if (0==1)
{
    string tmp = throwingFunc(); // throws
    __assert_fail(tmp,__LINE__,...); // dead code.
}

Actually it may be the compiler doing something funky with assert(0, msg); being special (assert(0,...) since the spec says for assert any compile time expression == 0 has the effect of assert(0). i.e. assert(0==1); is the same as assert(0);).

Proof


import std.stdio;
import core.exception;
bool foo() { return false;} // mess with the compiler's reasoning about the truthiness of the assert
void main() {
    scope(failure) {
        writeln("Not gonna happen");
    }

    try {
        static string throwingFunc() {
            throw new Exception("An exception");
        }
        assert(foo(), throwingFunc());
    } catch(Exception ex) {
        writeln("Exception");
    } catch(AssertError ex) {
        writeln("Assert");
    }
}

prints

Exception

Reply via email to