On Tue, Jun 13, 2017 at 5:43 AM, Niall Douglas via Boost < boost@lists.boost.org> wrote:
I will say that if Noexcept required this return_<T> type, it will be like outcome<T>, except that the error is transported using TLS instead of using the stack (please let me know if I'm wrong)
The only remaining difference is the fragmented API using that TLS.
And that semantically Outcome, like C APIs, lets users treat error codes as "the error" while Noexcept treats it as data, like in C++ error handling. If error codes are treated as "the error", then the error domain is limited to a single function. Consider these two functions: int f1(....); //returns 0 on success, 1-f1_error1, 2-f1_error2 int f2(....); //returns 0 on success, 1-f2_error1, 2-f2_error2 If f2 calls f1, if the error is communicated by an error code, f2 _must_ translate the error condition from the domain of f1 errors, to the domain of f2 errors. And this must be done at every level, which introduces many points in the code where subtle errors may occur, and that is in error handling code which is very difficult to test and debug. If you use exceptions, when f1 detects an error and throws an exception e.g. file_open_error (which may _contain_ an error code) that exception can pass through many levels in the code stack before caught, and there is no need for each level to take it, examine it and translate it like in C. The ability to propagate errors without touching them is even supported explicitly, in that throw can be used without arguments. For that reason, returning error codes as if that is "what" went wrong should not be supported.
However if Noexcept doesn't require a return_<T> then it is much difficult to force the use of the try functions. But it works yet.
I see advantages in this approach and I don't know which one is more efficient in the success and failure cases. Some measures will be more than welcome.
SG14 folk would reject any mandatory use of TLS as its performance is not bounded on some platforms (hidden malloc).
Worst case, a single hidden malloc that occurs ONCE when the thread starts. Consider the alternative: to burden passing values up the call stack, where performance may be critical, with having to transport anything and everything in case of an error.
do we want an error handling mechanism in C++ based on Swift error handling ;-) ? Do we want a library that emulates it as Boost.Noexcept in Boost?
I feel any design resembling C++ exceptions adds no value.
I agree, it only preserves as much of the value of C++ exceptions as possible, mainly the ability to propagate them from the point of the throw_ to the point of the catch_ without messing with them. A design *complementing* C++ exceptions with a significantly different
design makes much more sense, especially as you can then use both C++ exceptions AND your design together.
Except the "different" design is a step back and leads to subtle bugs in error handling code.