[Issue 15507] Throwable.message() should be pure @safe

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Tue Jan 5 09:56:33 PST 2016


https://issues.dlang.org/show_bug.cgi?id=15507

--- Comment #4 from Jonathan M Davis <issues.dlang at jmdavisProg.com> ---
(In reply to Dicebot from comment #3)
> Right. Well, this means my original concern remains. Overly restrictive
> method attributes in base classes has caused me more trouble than lack of
> any attributes there. I have no idea how to make stuff like `pure` or
> `nothrow` to work with overriding when it comes to some very base abstract
> methods.

You're basically forced to decide which set of restrictions you want, and all
derived classes are stuck with them. Do you want to be able to use the function
in pure code? Then it has to be pure. But if you want to be able to do stuff in
derived classes that isn't pure, then you can't make it pure...

Basically, attributes and inheritance do not play along nicely at all. That's
why we decided to remove opEquals, opCmp, toString, and toHash from Object -
you can't possibly get the attributes right for everyone (though unfortunately,
progress towards actually removing them has been minimal).

So, we have to decide whether it makes sense to restrict message to be nothrow,
pure, etc. or whether it makes sense to restrict the caller such that it has to
handle exceptions from message to be nothrow or make it so that it can't be
pure.

nothrow almost certainly makes sense - certainly, I can see there being a good
argument for considering it an Error for message to not work, and I seriously
doubt that anyone is going to be handling exceptions thrown from the message
member of an existing exception.

pure _might_ make sense (certainly, ideally it would be pure - but it would
mean that to do stuff like have a static variable, it would require a member
variable that referred to that static variable), but it would make some
implementations more unwieldy (e.g. using a static variable). Ultimately, all
pure would be doing here is making it so that you can call message in pure code
and so that you have to work at it to access mutable, "global" variables (and
thus won't do it accidentally). It doesn't really prevent you from doing
anything, but it doesn't protect you from much either, and it definitely
doesn't enable any optimizations. However, the  fact that pure _can_ be gotten
around in this case via member variables but that you can't sanely get around
the fact that the function isn't pure if you want to call it in pure code does
make it seem like making it pure is the more flexible choice.

@safe though is actually pretty questionable when you consider that there's a
decent chance that an exception class would have the const(char)[] be a slice
of a static array if it's trying to avoid allocations. To be safe, anyone who
wants to save the message needs to (i)dup it (and actually, the documentation
should probably reflect that).

A lot of it comes down to whether we want to restrict the caller more or the
classes that override message more.

If I had to pick right now, I'd go with @system pure nothrow.

--


More information about the Digitalmars-d-bugs mailing list