Here vector.push_back() might throw a std::bad_alloc. Under optimisation, the above code converts the throw of std::bad_alloc into a branch to early exit of an errored result<void>. So the exception throw and catch machinery is completely removed, and replaced with a fast branch. A very big win.
Unfortunately not. I expected this to be the case, but on the compilers I tested recently, the throw is not removed. Apparently the compilers consider the call to __cxa_throw observable behavior and never elide it. What compiler did?
I wrote this little program https://godbolt.org/g/FIV8nB and tested it under GCC, clang and VS2017. I had thought that -flto or /GL (LTCG) folded blatantly obvious throw-try-catch stanzas like that because benchmarking of MSVC them showed them to be real fast. In hindsight, I should have also run a disassembler on the resulting binaries, what MSVC actually is doing is following an early out path in _CxxThrowException, I count maybe 20-30 instructions. _CxxThrowException does check for an installed handler before going down early out. One can of course install into SEH/TEH arbitrary interception handlers upon throw, this is exactly what the debugger does of course on all platforms. Hence I can see that the compiler vendors will consider the throw keyword to be always observable behaviour, just like an atomic access. That sucks. Thanks for catching this behaviour, I'll reform the documentation to correct this and add a FAQ entry. I'll rework the macro to call your suggested API instead, and may remove it altogether. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/