Boost logo

Boost :

Subject: Re: [boost] Noexcept
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2017-06-13 09:39:29


On Tue, Jun 13, 2017 at 1:28 AM, Gavin Lambert via Boost <
boost_at_[hidden]> wrote:

> On 13/06/2017 18:12, Emil Dotchevski wrote:
>
>> In Noexcept, it is not correct to always use try_, for the same reason you
>> don't always use try with exception handling. That is only used if you
>> want
>> to _handle_ errors, not just check for errors; see the second Q&A here:
>> https://zajo.github.io/boost-noexcept/#qanda.
>>
>> Error checking with Noexcept depends on your choice of return type. For
>> example, if your return type is T *, you'd check for 0, if your return
>> type
>> is shared_ptr<T> or optional<T>, you'd check using the conversion to bool.
>>
>
> Is it still legal to have a function return the designated error value
> without actually setting an error?

It could happen, but note that it has to be explicit: you have to actually
return the invalid value, can't happen on its own. Similarly, you can
pass 0 for std::error_code to something like outcome<T>. In fairness, the
latter is perhaps more explicit, but it could still happen (I suppose, I
may be wrong about this.)

Regardless, the correct way to check for errors is to see if the result is
valid. This is the price one must pay when not using exception handling.

> Perhaps sometimes returning an empty shared_ptr is the successful return.

I can't imagine a function which returns shared_ptr<T> *and* which could
fail, to return an empty one in case of success. That said, in that
case all it means is that you can't use throw_ directly in a return
expression; or you could partially specialize throw_return<> for a specific
type of shared_ptr, if that's appropriate.

In an earlier version I had the main throw_return template undefined,
requiring users to specialize it to use throw_ in a function returning
given type, but I got convinced that it is not worth it.

> This in turn suggests that it's necessary to call try_ or similar to
> verify the difference between success and error, assuming that it does so
> using the TLS state rather than by inspecting the return value. (Or
> perhaps only inspects the TLS state when the return value is the error
> value, as a performance optimisation.)

try_ only inspects the TLS state. Similarly, try...catch also doesn't care
about return values.

Granted, if you throw you can't end up using an invalid value, but that's
just the nature of the beast when you can't throw: you must check for bad
results, and perhaps you should in some cases use a wrapper. I am not
arguing against that, but it is a good thing that Noexcept doesn't require
it, since a wrapper is almost certainly an overkill if you're returning,
say, shared_ptr<T>.


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