Can anyone explain this?
Nicholas Wilson
iamthewilsonator at hotmail.com
Tue Jun 5 09:58:43 UTC 2018
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
More information about the Digitalmars-d
mailing list