On 29/06/2017 18:34, Andrzej Krzemienski wrote:
Here, by "exception neutrality" I mean what function std::qsort is doing. It does not mention `try` or `catch` by any means, it can be compiled with C compiler, and yet it can propagate exceptions thrown by the callback.
That doesn't really follow. If code is C-compilable then it cannot have destructors and thus can only be exception safe if it does not perform any memory allocation or any other resource acquisition (eg. opening files). If you imagine any other pure C algorithm that calls a callback, unless it explicitly states that it's C++-exception-safe you shouldn't assume that you can safely throw an exception from that callback. (In fact it's generally a bad idea to assume that of a C++ algorithm too, unless explicitly stated.) If you happen to know that a given implementation has no side effects outside of the stack (and no destructors needed), then you could use setjmp/longjmp instead of exceptions, which at least conforms to a C contract. But that is not really any different from using exceptions in the first place. (Perhaps somewhat faster and less safe, since it skips the stack unwinding entirely.) (In the case of std::qsort specifically, it explicitly provides one overload taking a C++ linkage callback and one taking a C-linkage callback. Either one might be exception-safe, with the C++ callback perhaps slightly more likely, but in the absence of explicit guarantees you should probably be hesitant about it in both cases.) If you're referring only to exception propagation rather than safety (which kind of defeats the point of using exceptions in the first place), then no return-based solution could ever meet that; only exceptions themselves or a setjmp/longjmp alternative (which is obviously less safe, especially in C++ code), or some other compiler extension that would end up much like exceptions anyway.