Truly @nogc Exceptions?

Steven Schveighoffer schveiguy at gmail.com
Thu Sep 20 15:25:27 UTC 2018


On 9/20/18 11:06 AM, H. S. Teoh wrote:
> On Thu, Sep 20, 2018 at 08:48:13AM -0400, Steven Schveighoffer via Digitalmars-d wrote:
> [...]
>> But this means you still have to build msg when throwing the
>> error/exception. It's not needed until you print it, and there's no
>> reason anyway to make it allocate, even with RAII. For some reason D
>> forces msg to be built, but it does't e.g. build the entire stack
>> trace string before hand, or build the string that shows the exception
>> class name or the file/line beforehand.
> [...]
> 
> IIRC, originally the stacktrace was also built at exception construction
> time. But it was causing a major performance hit, so eventually someone
> changed the code to construct it lazily (i.e., only when the catcher
> actually tries to look it up).
> 
> I think it makes sense to also make .msg lazy, if the exception object
> is already carrying enough info to build the message when the catcher
> asks for it. And if the catcher doesn't ask for it, we saved an extra GC
> allocation (which is a plus even if we're not trying to go @nogc).

Except we DON'T construct the stack trace string, even lazily. If you 
look at the code I posted, it's output directly to the output buffer 
(via the sink delegate), without ever having allocated.

I think we can do that for the message too (why not, it's all 
supported). But either one (using GC at print time, or lazily outputting 
to buffer at print time) solves the biggest problem -- being able to 
construct an exception without the GC.

Plus, this nudges developers of exceptions to store more useful data. If 
you catch an exception that has details in it, possibly it is only going 
to be in the string, which you now have to *parse* to get out what the 
problem was. If instead it was standard practice just to store the 
details, and then construct the string later, more useful information 
would be available in the form of fields/accessors.

Think about this -- every ErrnoException that is thrown allocates its 
message via the GC on construction. Even if you catch that and just look 
at the errno code. Even with dip1008:

https://github.com/dlang/phobos/blob/6a15dfbe18f9151379f6337f53a3c41d12dee939/std/exception.d#L1625

-Steve


More information about the Digitalmars-d mailing list