|
Boost : |
Subject: Re: [boost] [err] RFC
From: Domagoj Saric (dsaritz_at_[hidden])
Date: 2015-11-17 03:06:06
On 17.11.2015. 4:28, Gavin Lambert wrote:
> On 17/11/2015 13:45, Domagoj Saric wrote:
>> Err enables the library writer to write a single API and a single
>> implementation:
>> err::fallible_result<bar_t, err_t> foo();
>> where fallible_result is the class template that wraps
>> temporaries/rvalues returned from functions and its member functions are
>> all declared with && (i.e. callable only on rvalues) so you get a
>> compiler error if you save it to an auto value and try to do anything
>> with it. The two exceptions are the implicit conversion operators to:
>> - bar_t, which will either return bar_t or throw err_t and which is used
>> for the 'EH code path'
>> bar_t my_bar( foo() );
>> - err::result_or_error<bar_t, err_t> which is used for the 'oldsk00l
>> nothrow error code path'
>> err::result_or_error<bar_t, err_t> maybe_bar( foo );
>> if ( maybe_bar ) { print( *maybe_bar ); }
>> else { log( maybe_bar.error() ); }
>
> Nitpicking on this, now that we're in an auto world it seems like a step
> backwards to introduce an API that relies on the declared type of a
> variable to alter behaviour. There should be methods on fallible_result
> that return these values explicitly instead.
Of course those methods exists. There was a lot more thought invested in
the library both WRT the API and codegen then 'meets the first post' -
which was more about the idea/principle itself - so I avoided 'spamming'
it with details...i.e. even if such a method did not exist there is
nothing stopping us from adding those ;)
>> Also, if the fallible_result rvalue is left uninspected and contains an
>> error its destructor will throw (which AFAICT should be safe considering
>> it is an rvalue and no other exception can possibly be active at the
>> same time)
>
> Throwing from a destructor can cause abrupt termination (or undefined
> behaviour in some compilers); there are no conditions in which it should
> be considered "safe".
That's not mandated by the standard...that would be a broken
compiler/standard library...
> Additionally I'm not convinced that no exception can be active at the
> same time. Consider function call parameters -- you could easily have
> one of these get constructed but not consumed yet, and then another
> parameter throws an exception, resulting in destruction of your object
> during the throw of an exception.
That can't happen: fallible_results are not meant for passing
parameters, and thanks to the rvalue semantics this is enforced by the
compiler rather than just by convention - even if you go to some lengths
to declare a function as taking a fallible_result (i.e. completely
contrary to what the type is for)
foo( fallible_result<bar_t> bar ); (instead of foo( bar ); )
you'll soon discover that you are doing something wrong because the
compiler won't let you do anything with that bar...
(and if the standard would let me declare a special && destructor for
rvalues there'd be no end to happiness, i.e. you'd get an error
immediately, at the declaration, and even better codegen in somecases...)
-- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk