|
Boost : |
Subject: Re: [boost] [outcome] success-or-failure objects
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2018-01-24 01:53:45
On Tue, Jan 23, 2018 at 5:36 PM, Gavin Lambert via Boost <
boost_at_[hidden]> wrote:
> On 24/01/2018 12:39, Emil Dotchevski wrote:
>
>> The motivation behind "doing something" in response a logic error is,
>> obviously, to soften the impact of the bug on the user. The problem is
>> that
>> without knowing what went wrong, "doing something" might make the impact
>> much worse. If you step on a mine, it's probably not a good idea to keep
>> on
>> walking.
>>
>
> In the general case I completely agree. I'm just pointing out that the
> general case is not all cases.
>
> Granted, once the kind of errors shift from null references to things like
> use-after-free or double-free (or unchecked out-of-bounds), then all bets
> are off and chaos can and will ensue with little hope of recovery (unless
> the app has been careful to correctly use arena allocators). These types
> of errors are less common with modern smart pointers, though.
>
>
> But we're not even really talking about those things, we're talking about
> parameter validation and state preconditions.
>
I was talking about logic errors. Bugs.
> Ideally, public APIs should not trust their callers to pass sane arguments
> or refrain from calling a method in an inappropriate state, and should by
> default verify this and throw (with an option to disable it in release
> builds for performance, or keep doing it).
That depends on the API. It is the responsibilty of the caller to not
violate the documented preconditions when calling a function, and if he
does, that is a logic error. The whole point of defining preconditions is
to say that all bets are off otherwise.
This is not to be confused with a function documenting that if this or that
argument is outside of some valid range it throws exceptions. In this case
it is NOT a logic error to call it with "bad" arguments, because the
function specifies what it does in that case.
> This is why things like debug iterators exist. (And should be used more
> often for custom iterators.)
>
Debug iterators exist to help find logic errors, not to define behavior in
case of logic errors. Do note that debug iterators abort the program in
case of logic errors, rather than throw exceptions.
> This is an oxymoron. If the state is undefined, you don't know if it is
>> destructible.
>>
>
> Tell that to moved-from objects.
>
> (I'm using "undefined" in the English "it could be in one of many
> intermediate states" sense, not the Standard "dogs and cats living
> together" sense. Mutexes might be broken, the data might be silly, and the
> class invariant might have been violated, but it is probably still
> destructible.)
>
And I'm using its domain-specific meaning: moved-from objects don't have
undefined state, they have well-defined but unspecified state.
More to the point, this situation is NOT a logic error, because the object
can be safely destroyed. Logic error would be if the object ends up in
undefined state, which may or may not be destructible. You most definitely
don't want to throw a C++ exception in this case.
Emil
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk