Boost logo

Boost :

Subject: Re: [boost] expected/result/etc
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2016-01-28 07:36:33


On 28 Jan 2016 at 0:49, Michael Marcin wrote:

> If the direct caller can handle the error returning an error enum
> instead of a std::error_code will often be better. It looks like the
> DXXXXR0 expected proposal allows for this.

The way I've done it is to define a custom error code category per
category of error throwing thing, thereby naturally extending C++
11/Boost error codes. It may seem like an awful lot of boilerplate
when you just want an enum really, but trust me that it is worth the
effort - you get stuff like free error_code to exception throw to
error_code conversions (you specifically need that machinery to
return error codes from constructors) and all sorts of other goodies
like debug printing. I'd recommend forget about enums for error
coding, extend error_code as it was designed to be extended and
accept the boilerplate which is fire and forget anyway.

I will tell you one thing though: I just don't get the need for
error_code and error_condition to be different in real world usage. I
appreciate the original desire for there to be a type distinction
matching the semantic distinction, but in any code I've written so
far the custom category plus error_code is as much as I need. Outcome
reflects my experience here, and does not support error_condition.

> A variant is a good implementation for many types.
> And I think clearly the right default behavior.
> However, I'm not convinced that a variant is always the best implementation.
>
> Take for example an expected<void*,error_enum>.
> Although I haven't done tests I'd be reasonable confident returning this
> by value would perform worse than returning
> std::pair<void*,error_enum>.
>
> First, the machinery is going to make it store an extra byte at least
> for the variant discriminator.
>
> Then, you likely branch before the copy (maybe optimized away by a smart
> variant implementation).
>
> In fact in *most* cases of returning a pointer and error_enum you should
> be able to get away with returning a the equivalent of
> union { void*, error_enum }
> As *most* error_enums are relatively small and have values smaller than
> any valid heap or stack pointer.
> It would be nice to be able to opt in for this.
>
> More generally given
> - an error_enum with an OK or 'not an error' value
> - a T that is cheap to default construct and cheap to copy/move
> Is the library solution better than returning a pair<T, error_enum>?
> Or a function returning an error_enum with an out param?

My dissatisfaction with the quality of output overhead of other
solutions led me to invest very significant time into this aspect of
Outcome, and there are per-commit unit tests ensuring ideal code
quality output for various canned use cases at
https://github.com/ned14/boost.outcome/tree/master/test/constexprs.

Any hand rolled solution will likely be more surprising unless the
author invests a similar amount of tuning effort. You would be
surprised what upsets compiler optimisers sometimes.

Niall

-- 
ned Productions Limited Consulting
http://www.nedproductions.biz/ 
http://ie.linkedin.com/in/nialldouglas/



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