Boost logo

Boost :

Subject: Re: [boost] [review] Review of Outcome v2 (Fri-19-Jan to Sun-28-Jan, 2018)
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2018-02-01 19:04:25


2018-02-01 19:13 GMT+01:00 Emil Dotchevski <emildotchevski_at_[hidden]>:

> On Thu, Feb 1, 2018 at 2:51 AM, Andrzej Krzemienski <akrzemi1_at_[hidden]>
> wrote:
>
>> Boost.Outcome solves the problem decently: you get a compiler error or a
>> compiler warning
>>
>
> Do you? What if you have:
>
> result<void> foo();
>
> void bar()
> {
> foo();
> }
>
> What compile error will that generate?
>

"ignoring returned value of type 'outcome_v2_f1696316::result<void>',
declared with attribute nodiscard [-Werror=unused-result]"

online example: https://wandbox.org/permlink/5vICxckvVG6QO0n1

> Now, in Boost.Noexcept, if the programmer forgets to test for the failure
>> (with `try_`), the subsequent function is still executed with the default
>> value of type `T` returned from the funciton that failed. Because in
>> Boost.Noexcept when function fails it returns a default-constructed `T`.
>>
>
> The idea in Noexcept is that since the function _must_ return something if
> there is an error, it returns throw_return<T>() but that is not automatic;
> the user still has to say e.g. return throw_(error()).
>

I understand the constraints you are under. I also acknowledge that this is
the best one can do. Nonetheless, I still see the limitation of the
solution. If a third party function is returning a type representing a
resource, and this type does not provide a default constructor, there is no
way to "throw_". You cannot even customize `throw_return<T>()` because what
value would you return? You are reporting failure because you cannot
acquire the resource. And because it is a third-party interface, you cannot
adapt the type. So, in the end, there will be functions where you cannot
apply Boost.Noexcept.

>
>
>> And when you check it systematically it is all ok, but then you forget
>> (and this is a tedious task), you violate the contracts. No compile-time
>> check, no run-time check.
>>
>
> In Noexcept there _is_ run-time check: if noexcept_::has_current_error()
> is true at the time a thread terminates, it invokes std::terminate(). Not
> ideal, and won't take action if the thread never terminates -- and it may
> never terminate because, like in Outcome, if the caller doesn't check at
> every function call, the program keeps going.
>

I was imprecise. you do have a run-time check, but it comes too late: it
does not prevent functions to be called with failed preconditions.

>
>
>> I consider this a serious issue.
>>
>
> It is, programmers forget to check for errors all the time.
>

And Boost.Outcome helps detect these situations at compile-time (of course,
at the expense of controlling the return type).

>
>> And taking into consideration the advantages of Boost.Noexcept you
>> mention, I can only conclude that Boost.Noexcept is superior to
>> Boost.Outcome in one aspect but inferior in another.
>>
>
> The two libraries solve different problems.
>

Indeed.

> Outcome helps you avoiding exception handling, so it assumes you can
> freely use result<T,E> throughout your interfaces.
>

Well, it can help you avoid exceptions. But it also helps you deal with the
lack of exception handling. As you say, the trade-off is that you use
`result` in return type.

> Noexcept helps you deal with a lack of exception handling, so it assumes
> that at least some of the interfaces are beyond your control, and doesn't
> impose a return type.
>

Yes, here the trade-off is, no altering of the return type, but unsafe
consequences when you forget to check for "thrown" exceptions. And there
must exist a "spare" value in the returned type.

There are benefits to using a special return type (to protect against using
> an invalid value), but Noexcept leaves that to the user because return
> values don't transport errors, just the T; you could e.g. use
> std::optional<T>.
>

And user may not be able to make this decision because he may not be in
control of the return type.

Regards,
&rzej;


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk