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
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 which is used for the 'oldsk00l nothrow error code path' err::result_or_error 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