Sutter's ISO C++ Trip Report - The best compliment is when someone else steals your ideas....

wjoe none at example.com
Tue Jul 10 14:20:25 UTC 2018


On Sunday, 8 July 2018 at 20:55:15 UTC, John Carter wrote:
> On Saturday, 7 July 2018 at 01:18:21 UTC, wjoe wrote:
>> But that's not how D works. It throws an Error which can be 
>> caught.
>>
>> If people are allowed to do something they assume it's 
>> legitimate.
>>
>> It should be a compile time error to catch an Error, but it 
>> doesn't even emit a warning and it seems to work well which is 
>> probably proof enough for people to assume it's good.
>
> I got myself so tangled up in knots with the equivalent in 
> Ruby.... You can "rescue" the base Exception class... which 
> initially I did everywhere to try give better error messages...
>
> Which more often than not would result in everything going 
> weird and insane instead of useful.
>
> Eventually I replaced _every_ "rescue Exception" with "rescue 
> StandardError" and life improved majorly.
>
> Seriously folks, trying to "catch and handle" a programming bug 
> leads to the very dark side of life.
>
> Especially in a 'C/C++/D" like language where the exception is 
> concrete evidence that the system is _already_ in an undefined 
> and unreliable state.

I'll keep that advice in mind.

In case of the program I made with std.concurrency, I did not 
catch Throwable to try to recover, but to be able to debug the 
cause because there was no stack trace printed out or any 
indication at all that something went wrong. And because the 
debugger wouldn't break on anything either and a catch block at 
least allowed for setting a breakpoint there it seemed like an 
idea.
A catch all Exception didn't trigger and the thread still just 
vanished. So I just gave it a shot and broadened that to 
Throwable to rule out this case, too, and sure enough an Error 
was caught.

Would have been a lot easier to debug if that Error brought down 
the whole thing with it and then there wouldn't have been a 
reason to catch Throwable in the first place.

Except, a D program which is terminated by the D runtime via 
Error mechanism, at least on Linux, prints an Error with a stack 
trace and then exits with code 1. That's a normal exit since 
positive exit codes are supposed to be handled by the caller 
something akin to success, or file not found.
In my opinion this behavior is a defect in the D runtime. It 
should abort abnormally and indicate that fact with an exit code 
of -6, or the OS equivalent of SIGABRT.

It is really annoying if you run the program in a debugger, too, 
which simply tells you the program exited normally and you can't 
walk the stack trace, print variables, etc.

The behavior on segfault is identical to a C program (exit code 
-11, SIGSEGV), but this is probably because the OS terminates the 
program before the runtime gets any opportunity to throw an 
Error. Meaning you don't get a stack trace, however a debugger 
breaks exactly at the offending line in the source code.

Before Jonathan's explanation on how the Error mechanism works I 
had considered abusing the Error mechanism to do some cleanup of 
secrets in memory (cached passwords or some such) in case of an 
abnormal termination, etc. - the reasoning being it's possible 
and if it can reliably print a stack trace, why couldn't it do 
some zeroing of RAM prior to that, right?
But thinking about it some more, all the things I would have 
considered doing in a catch Error block can be solved without 
catching.
If catch *Error{} would be a compile time error, I would have 
just accepted the fact and came up with alternatives all the 
same. Saving him a lot of nerves in the process. So, thanks 
again, Jonathan, for bearing with me :) Much appreciated!

Considering the implications, it really baffles me that there 
isn't so much as a warning when the compiler encounters: catch 
*Error...


More information about the Digitalmars-d mailing list