Boost logo

Boost :

Subject: Re: [boost] [outcome] Review of Outcome
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2017-05-29 11:41:11


>> 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/

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk